package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.lfasr.concurrent.ConcurrentLockAspect;
import com.xbongbong.paas.business.rule.RuleBusinessLogger;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.MultiUnitItemPoJo;
import com.xbongbong.paas.field.SaasParticularAttributePoJo;
import com.xbongbong.paas.help.FormDataValidateProductHelp;
import com.xbongbong.paas.help.ProSaveHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.pojo.InfoArrPojo;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasProcessDataModel;
import com.xbongbong.paas.model.PaasProcessTemplateModel;
import com.xbongbong.paas.pojo.FieldAttrEntityForImport;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.dto.ImportFormDataDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.dto.WarehouseCheckDTO;
import com.xbongbong.paas.pojo.imports.CellTitlePojo;
import com.xbongbong.paas.pojo.imports.CellValuePojo;
import com.xbongbong.paas.pojo.imports.RowGroupPojo;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CloneUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.PageHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.businessproduct.pojo.dto.BusinessProductListDTO;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.detailtab.vo.ProductSummaryVO;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.domain.entity.UpdateDataValueEntity;
import com.xbongbong.pro.enums.errorcodes.BuinessDefaultErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ImportErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.InstockErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.OutstockErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.WarehouseErrorCodeEnum;
import com.xbongbong.pro.inventory.pojo.dto.InventoryDeleteBatchDTO;
import com.xbongbong.pro.inventory.pojo.dto.InventoryEditAttrUpdateDTO;
import com.xbongbong.pro.inventory.pojo.dto.InventoryResetInstockIdDTO;
import com.xbongbong.pro.inventory.pojo.dto.InventoryResetOutstockIdDTO;
import com.xbongbong.pro.inventory.pojo.dto.InventoryUpdateBatchDTO;
import com.xbongbong.pro.inventory.pojo.dto.InventoryUpdateByBusinessRuleDTO;
import com.xbongbong.pro.inventory.pojo.dto.InventoryUpdateDTO;
import com.xbongbong.pro.inventory.pojo.vo.InventoryDeleteBatchVO;
import com.xbongbong.pro.inventory.pojo.vo.InventoryResetInstockIdVO;
import com.xbongbong.pro.inventory.pojo.vo.InventoryResetOutstockIdVO;
import com.xbongbong.pro.inventoryproduct.pojo.dto.FormatInventoryProductDTO;
import com.xbongbong.pro.inventoryproduct.pojo.dto.InventoryProductDeleteBatchDTO;
import com.xbongbong.pro.inventoryproduct.pojo.dto.InventoryProductListDTO;
import com.xbongbong.pro.inventoryproduct.pojo.vo.InventoryProductListVO;
import com.xbongbong.pro.listbatch.pojo.dto.AddLabelDTO;
import com.xbongbong.pro.log.pojo.dto.RuleBusinessLogDTO;
import com.xbongbong.pro.product.pojo.dto.PagingProductDTO;
import com.xbongbong.pro.product.pojo.vo.DetailProductVO;
import com.xbongbong.pro.product.pojo.vo.PagingProductVO;
import com.xbongbong.pro.productbaseinfo.pojo.dto.ProductBaseInfoDeleteBatchDTO;
import com.xbongbong.pro.thread.ThreadPoolBeanConfig;
import com.xbongbong.pro.warehouse.pojo.vo.WarehouseListVO;
import com.xbongbong.saas.analytical.impl.InventoryValidateAnalyticalServiceImpl;
import com.xbongbong.saas.annotation.BusinessTypeToServiceAnnotation;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.ProductConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.InventoryProductEntity;
import com.xbongbong.saas.domain.entity.ProductBaseInfoEntity;
import com.xbongbong.saas.domain.entity.ProductStockEntity;
import com.xbongbong.saas.domain.entity.ProductWarehouseEntity;
import com.xbongbong.saas.domain.entity.ext.InventoryEntityExt;
import com.xbongbong.saas.domain.entity.ext.InventoryProductEntityExt;
import com.xbongbong.saas.domain.entity.ext.ProductEntityExt;
import com.xbongbong.saas.enums.BusinessProductEnum;
import com.xbongbong.saas.enums.BusinessTypeToServiceEnum;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.InstockTypeEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperatePageEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.OutstockTypeEnum;
import com.xbongbong.saas.enums.RelativeProductEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.UpdateDataTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.InstockEnum;
import com.xbongbong.saas.enums.business.InventoryEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.dictionary.InventoryNewStatusEnum;
import com.xbongbong.saas.enums.dictionary.InventoryTypeEnum;
import com.xbongbong.saas.enums.product.AssembleProductEnum;
import com.xbongbong.saas.enums.product.InventoryProductEnum;
import com.xbongbong.saas.enums.product.OutstockProductEnum;
import com.xbongbong.saas.enums.product.TransferProductEnum;
import com.xbongbong.saas.enums.subform.ProductStockSubFormEnum;
import com.xbongbong.saas.enums.subform.ProductWarehouseSubFormEnum;
import com.xbongbong.saas.help.BatchSeqExplainHelp;
import com.xbongbong.saas.help.DefaultAttrHelp;
import com.xbongbong.saas.help.ExplainHelp;
import com.xbongbong.saas.help.ImportHelper;
import com.xbongbong.saas.help.LogHandleHelp;
import com.xbongbong.saas.help.RelativeProductHelp;
import com.xbongbong.saas.help.SaasUpdateHelp;
import com.xbongbong.saas.help.workflow.ProductValidateHelp;
import com.xbongbong.saas.model.InventoryModel;
import com.xbongbong.saas.model.InventoryProductModel;
import com.xbongbong.saas.model.ProductBaseInfoModel;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.model.ProductStockModel;
import com.xbongbong.saas.model.ProductWarehouseModel;
import com.xbongbong.saas.model.SpecificationModel;
import com.xbongbong.saas.service.FormatSpecialBusinessService;
import com.xbongbong.saas.service.InstockService;
import com.xbongbong.saas.service.InventoryProductService;
import com.xbongbong.saas.service.InventoryService;
import com.xbongbong.saas.service.OutstockService;
import com.xbongbong.saas.service.ProductBaseInfoService;
import com.xbongbong.saas.service.ProductService;
import com.xbongbong.saas.service.toolbox.help.LogHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static com.xbongbong.saas.enums.RelativeProductEnum.BARCODE;
import static com.xbongbong.saas.enums.RelativeProductEnum.BATCH;
import static com.xbongbong.saas.enums.RelativeProductEnum.GUARANTEE_PERIOD;
import static com.xbongbong.saas.enums.RelativeProductEnum.MEMO;
import static com.xbongbong.saas.enums.RelativeProductEnum.NAME;
import static com.xbongbong.saas.enums.RelativeProductEnum.NUM;
import static com.xbongbong.saas.enums.RelativeProductEnum.PRODUCE_DATE;
import static com.xbongbong.saas.enums.RelativeProductEnum.PRODUCT_NO;
import static com.xbongbong.saas.enums.RelativeProductEnum.PROFIT_STATUS;
import static com.xbongbong.saas.enums.RelativeProductEnum.SPECIFICATION;
import static com.xbongbong.saas.enums.RelativeProductEnum.STOCK;
import static com.xbongbong.saas.enums.RelativeProductEnum.UNIT;
import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author feng.zheng
 * @version v1.0
 * @date 2019/2/14 21:04
 * @since v1.0
 */
@Service("inventoryService")
@BusinessTypeToServiceAnnotation(businessService = BusinessTypeToServiceEnum.INVENTORY)
public class InventoryServiceImpl implements InventoryService, FormatSpecialBusinessService {

    private static final Logger LOG = LoggerFactory.getLogger(InventoryServiceImpl.class);

    @Resource
    private DefaultAttrHelp defaultAttrHelp;
    @Resource
    private SaasUpdateHelp saasUpdateHelp;
    @Resource
    private ExplainHelp explainHelp;
    @Resource
    private ProductModel productModel;
    @Resource
    private ProductWarehouseModel productWarehouseModel;
    @Resource
    private InventoryModel inventoryModel;
    @Resource
    private InventoryProductService inventoryProductService;
    @Resource
    private ProductBaseInfoService productBaseInfoService;
    @Resource
    private InventoryProductModel inventoryProductModel;
    @Resource
    private ProductBaseInfoModel productBaseInfoModel;
    @Resource
    private SpecificationModel specificationModel;
    @Resource
    private InstockService instockService;
    @Resource
    private OutstockService outstockService;
    @Resource
    private ImportHelper importHelper;
    @Resource
    private ProductStockModel productStockModel;
    @Resource
    private PaasProcessTemplateModel paasProcessTemplateModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    @Lazy
    private RuleBusinessLogger ruleBusinessLogger;
    @Resource
    private FormDataValidateProductHelp formDataValidateProductHelp;
    @Resource
    private ProductService productService;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private ThreadPoolBeanConfig threadPoolBeanConfig;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private PaasProcessDataModel paasProcessDataModel;
    @Resource
    private RelativeProductHelp relativeProductHelp;
    @Resource
    private LogHelp logHelp;
    @Resource
    private LogHandleHelp logHandleHelp;
    @Resource
    private InventoryValidateAnalyticalServiceImpl inventoryAnalyticalService;
    @Resource
    private ConcurrentLockAspect concurrentLockAspect;
    @Resource
    private ProductValidateHelp productValidateHelp;

    /**
     * 盘点单保存前saas特殊校验
     *
     * @param validateDataDTO saas特殊校验数据入参
     * @throws XbbException 业务异常
     * @author feng.zheng
     * @date 2019/1/18
     */
    @Override
    public void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException {
        inventoryAnalyticalService.beforeSave(validateDataDTO);
    }


    /**
     * 检验批次是否存在
     * @param outProductJSONArray
     * @param corpid
     * @throws XbbException
     */
    private void checkBatchIsRight(boolean isNew, JSONArray outProductJSONArray, String corpid,Long wareHouseId) throws XbbException {
        List<Long> pageProductIds = new ArrayList<>();
        pageProductIds.add(-1L);
        for (int i = 0; i < outProductJSONArray.size(); i++) {
            JSONObject productObj = outProductJSONArray.getJSONObject(i);
            Long productId = productObj.getJSONObject(SelectProductEnum.PRODUCT.getAttr()).getLong(StringConstant.DATA_ID);
            pageProductIds.add(productId);
        }
        // 需要查询的字段
        List<String> fieldList = Arrays.asList(ProductStockSubFormEnum.getAttrConnectData(ProductStockSubFormEnum.PARENT_ID), ProductStockSubFormEnum.getAttrConnectData(ProductStockSubFormEnum.BATCH));
        List<ProductStockEntity> productStockEntityList = productStockModel.getValidBatchInfoList(pageProductIds, corpid, wareHouseId, null, fieldList);
        Map<String, Set<String>> productStockMap = new HashMap<>(productStockEntityList.size());
        productStockEntityList.forEach(item -> {
            String key = item.getProductId() + "_" + item.getWarehouseId();
            if (productStockMap.containsKey(key)) {
                productStockMap.get(key).add(item.getBatch());
            } else {
                Set<String> batchSet = new HashSet<>();
                batchSet.add(item.getBatch());
                productStockMap.put(item.getProductId() + "_" + wareHouseId, batchSet);
            }
        });
        for (int i = 0; i < outProductJSONArray.size(); i++) {
            JSONObject productObj = outProductJSONArray.getJSONObject(i);
            String productId = productObj.getString(StringConstant.SAAS_LINK_BUSINESS_ID);
            String batch = productObj.getString(StringConstant.BATCH);
            String key = productId + "_" + wareHouseId;
            if ( StringUtil.isNotEmpty(batch) && (productStockMap.get(key) == null || !productStockMap.get(key).contains(batch))) {
                throw new XbbException(OutstockErrorCodeEnum.API_ERROR_212026, OutstockErrorCodeEnum.API_ERROR_212026.getMsg());
            }
        }
    }

    /**
     * 盘点单保存后逻辑
     *
     * @param saasFormSaveDTO saas保存数据
     * @throws XbbException 业务异常
     * @author feng.zheng
     */
    @Override
    public void afterSave(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        String corpid = saasFormSaveDTO.getCorpid();
        Long id = saasFormSaveDTO.getNewPaasFormDataEntity().getId();
        JSONObject newData = saasFormSaveDTO.getNewData();
        JSONArray productArray = newData.getJSONArray(InventoryEnum.PRODUCT.getAttr());
        Long warehouseId = FastJsonHelper.getLongOrDefaultFromFormData(newData, InventoryEnum.WAREHOUSE_ID.getAttr(), 0L);
        Long formId = saasFormSaveDTO.getNewPaasFormDataEntity().getFormId();
        String inventoryType = FastJsonHelper.getStringOrDefaultFromFormData(newData, InventoryEnum.INVENTORY_TYPE.getAttr(), InventoryTypeEnum.STANDARD_INVENTORY.getCode());
        //已经出库或入库，不允许编辑
        boolean hasInOrOut = !Objects.equals(newData.getInteger(InventoryEnum.INSTOCK_ID.getAttr()),0) && !Objects.equals(newData.getInteger(InventoryEnum.OUTSTOCK_ID.getAttr()),0)
                && !Objects.isNull(newData.get(InventoryEnum.INSTOCK_ID.getAttr())) && !Objects.isNull(newData.get(InventoryEnum.OUTSTOCK_ID.getAttr()));
        Boolean productCanSee = saasFormSaveDTO.getSaasNeedRedundantAttrPoJo().getAttrCanSee(InventoryEnum.PRODUCT.getAttr());
        // 更新盘点单关联产品
        if (saasFormSaveDTO.getIsNew() || (productCanSee && !hasInOrOut)){
            saveProduct(saasFormSaveDTO.getCorpid(), id, warehouseId, productArray, formId,saasFormSaveDTO.getIsNew());
        }
        // 生成出入库单
        generateStockSheet(saasFormSaveDTO);
    }


    /**
     * 保存盘点单产品
     *
     * @param corpid       公司id
     * @param inventoryId  盘点单id
     * @param warehouseId  仓库id
     * @param productArray 产品
     * @param formId       表单id
     * @param isNew
     * @throws XbbException 异常
     */
    private void saveProduct(String corpid, Long inventoryId, Long warehouseId, JSONArray productArray, Long formId, Boolean isNew) throws XbbException {
        Map<Long, InventoryProductEntity> orginProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, ProductBaseInfoEntity> orginProductBaseInfoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (!isNew) {
            //非新建情况下，取得盘点单编辑前的关联产品
            List<InventoryProductEntity> inventoryProductEntityList = inventoryProductModel.getProductsByInventoryId(inventoryId,corpid, Arrays.asList(DelEnum.NORMAL.getDel(), DelEnum.APPROVE_FAILED.getDel()));
            List<Long> refProductIdList = new ArrayList<>(inventoryProductEntityList.size());
            for (InventoryProductEntity inventoryProductEntity : inventoryProductEntityList) {
                orginProductMap.put(inventoryProductEntity.getId(), inventoryProductEntity);
                refProductIdList.add(inventoryProductEntity.getId());
            }
            if (!refProductIdList.isEmpty()) {
                List<ProductBaseInfoEntity> productBaseInfoList = productBaseInfoModel.getProductBaseInfoList(corpid, XbbRefTypeEnum.INVENTORY_PRODUCT.getCode(), refProductIdList);
                productBaseInfoList.forEach(item -> orginProductBaseInfoMap.put(item.getRefId(), item));
            }
        }
        //新增产品
        //编辑产品
        List<InventoryProductEntity> productUpdateList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, PaasFormDataEntityExt> productMap = formDataValidateProductHelp.product2saveMap(corpid,productArray);
        List<ProductBaseInfoEntity> addProductBaseInfoList = new ArrayList<>();
        List<ProductBaseInfoEntity> updateProductBaseInfoList = new ArrayList<>();
        Integer sort = 0;
        List<InventoryProductEntity> inventoryProductList = new ArrayList<>();
        Map<Integer, InventoryProductEntity> inventoryProductMap = new HashMap<>(productArray.size());
        Map<Integer, ProductBaseInfoEntity> inProductBaseInfoMap = new HashMap<>(productArray.size());
        for (int i = 0; i < productArray.size(); i++) {
            JSONObject jsonObject = productArray.getJSONObject(i);
            Long pageProductId = jsonObject.getLong(SelectProductEnum.PRODUCT.getAttr());
            Long businessProductId = jsonObject.getLong(BusinessConstant.PRODUCT_SUB_ID);
            Double productNum = jsonObject.getDouble(InventoryProductEnum.NUM.getAttr());
            Double oriNum = jsonObject.getDouble(InventoryProductEnum.STOCK.getAttr());
            String memo = jsonObject.getString(InventoryProductEnum.MEMO.getAttr());
            boolean addProductFlag = formDataValidateProductHelp.addProductFlag(businessProductId);
            InventoryProductEntity inventoryProductEntity;
            if (addProductFlag) {
                //新增产品
                inventoryProductEntity = new InventoryProductEntity();
//                productAddList.add(transferProductEntity);
//                productBaseInfoEntity = new ProductBaseInfoEntity();
            } else if (orginProductMap.containsKey(businessProductId)) {
                //编辑产品
                inventoryProductEntity = orginProductMap.get(businessProductId);
                if (Objects.equals(DelEnum.APPROVE_FAILED.getDel(), inventoryProductEntity.getDel())) {
                    inventoryProductEntity.setDel(DelEnum.NORMAL.getDel());
                }
                productUpdateList.add(inventoryProductEntity);
                //只剩删除的产品
                orginProductMap.remove(businessProductId);
            } else {
                //删除产品
                continue;
            }
            JSONObject productData = productMap.get(pageProductId).getData();
            inventoryProductEntity.setCorpid(corpid);
            inventoryProductEntity.setInventoryId(inventoryId);
            inventoryProductEntity.setParentId(productData.getLong(ProductEnum.PARENT_ID.getAttr()));
            inventoryProductEntity.setProductId(pageProductId);
            inventoryProductEntity.setProductName(productData.getString(ProductEnum.NAME.getAttr()));
            inventoryProductEntity.setProductNo(productData.getString(ProductEnum.PRODUCT_NO.getAttr()));
            inventoryProductEntity.setProductSpecification(productData.getString(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr()));
            inventoryProductEntity.setProductNum(productNum);
            inventoryProductEntity.setOriNum(oriNum);
            inventoryProductEntity.setProductPrice(productData.getDouble(ProductEnum.PRICE.getAttr()));
            inventoryProductEntity.setFormId(formId);
            inventoryProductEntity.setWarehouseId(warehouseId);
            inventoryProductEntity.setSort(sort);
            inventoryProductEntity.setMemo(memo);
            Integer enableMultiUnit = productData.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getAttr());
            if (Objects.equals(enableMultiUnit, 1)) {
                jsonObject.remove(ProductConstant.UNIT_RATE);
                jsonObject.remove(ProductConstant.TRANSFORM_UNIT_RATE);
                inventoryProductEntity.setProductUnit(jsonObject.getString(ProductEnum.UNIT.getAttr()));
            }else {
                inventoryProductEntity.setProductUnit(productData.getString(ProductEnum.UNIT.getAttr()));
                jsonObject.put(InventoryProductEnum.UNIT.getAttr(),productData.getString(ProductEnum.UNIT.getAttr()));
            }
            inventoryProductEntity.setData(jsonObject);
            inventoryProductEntity.setUpdateTime(DateTimeUtil.getInt());
            inventoryProductEntity.setBatch(jsonObject.getString(TransferProductEnum.BATCH.getAttr()));
            inventoryProductEntity.setProduceDate(jsonObject.getLong(AssembleProductEnum.PRODUCE_DATE.getAttr()));
            if (Objects.nonNull(jsonObject.getLong(InventoryProductEnum.GUARANTEE_PERIOD.getAttr()))){
                inventoryProductEntity.setGuaranteePeriod(jsonObject.getLong(InventoryProductEnum.GUARANTEE_PERIOD.getAttr()) * TimeConstant.SECONDS_PER_DAY);
            }
            if (addProductFlag) {
                inventoryProductList.add(inventoryProductEntity);
                inventoryProductMap.put(i, inventoryProductEntity);
                // 生成出入库单，会用到这个属性
//                jsonObject.put(BusinessConstant.REF_PRODUCT_ID, inventoryProductEntity.getId());
            }
            //额外信息
            if (StringUtil.isNotEmpty(jsonObject.getString(InventoryProductEnum.BATCH.getAttr())) && !orginProductBaseInfoMap.containsKey(inventoryProductEntity.getId())) {
                JSONObject productBaseInfoData = new JSONObject();
                productBaseInfoData.putAll(jsonObject);
                ProductBaseInfoEntity productBaseInfoEntity = new ProductBaseInfoEntity();
                productBaseInfoEntity.setCorpid(corpid);
                productBaseInfoEntity.setFormId(formId);
                productBaseInfoEntity.setRefType(XbbRefTypeEnum.INVENTORY_PRODUCT.getCode());
                productBaseInfoEntity.setRefId(inventoryProductEntity.getId());
                productBaseInfoEntity.setBatch(jsonObject.getString(InventoryProductEnum.BATCH.getAttr()));
                productBaseInfoEntity.setProduceDate(jsonObject.getLong(InventoryProductEnum.PRODUCE_DATE.getAttr()));
                if (Objects.nonNull(jsonObject.getLong(InventoryProductEnum.GUARANTEE_PERIOD.getAttr()))){
                    productBaseInfoEntity.setGuaranteePeriod(jsonObject.getLong(InventoryProductEnum.GUARANTEE_PERIOD.getAttr()) * TimeConstant.SECONDS_PER_DAY);
                }
                productBaseInfoEntity.setMemo(memo);
                productBaseInfoEntity.setData(productBaseInfoData);
                productBaseInfoEntity.setDel(0);
                productBaseInfoEntity.setAddTime(DateTimeUtil.getInt());
                productBaseInfoEntity.setUpdateTime(DateTimeUtil.getInt());
//                addProductBaseInfoList.add(productBaseInfoEntity);
                inProductBaseInfoMap.put(i, productBaseInfoEntity);
            } else if (!addProductFlag && orginProductBaseInfoMap.containsKey(inventoryProductEntity.getId())) {
                ProductBaseInfoEntity productBaseInfoEntity = orginProductBaseInfoMap.get(inventoryProductEntity.getId());
                productBaseInfoEntity.setBatch(jsonObject.getString(TransferProductEnum.BATCH.getAttr()));
                productBaseInfoEntity.setProduceDate(jsonObject.getLong(AssembleProductEnum.PRODUCE_DATE.getAttr()));
                if (Objects.nonNull(jsonObject.getLong(TransferProductEnum.GUARANTEE_PERIOD.getAttr()))){
                    productBaseInfoEntity.setGuaranteePeriod(jsonObject.getLong(TransferProductEnum.GUARANTEE_PERIOD.getAttr()) * TimeConstant.SECONDS_PER_DAY);
                }
                productBaseInfoEntity.setMemo(jsonObject.getString(TransferProductEnum.MEMO.getAttr()));
                updateProductBaseInfoList.add(productBaseInfoEntity);
                orginProductBaseInfoMap.remove(inventoryProductEntity.getId());
            }
            sort++;
        }
        inventoryProductModel.insertBatch(inventoryProductList);
        inventoryProductMap.forEach((i, inventoryProduct)->{
            JSONObject jsonObject = productArray.getJSONObject(i);
            Long id = inventoryProduct.getId();
            // 生成出入库单，会用到这个属性
            jsonObject.put(BusinessConstant.REF_PRODUCT_ID, id);
            if (inProductBaseInfoMap.containsKey(i)) {
                ProductBaseInfoEntity productBaseInfoEntity = inProductBaseInfoMap.get(i);
                productBaseInfoEntity.setRefId(id);
                inProductBaseInfoMap.put(i, productBaseInfoEntity);
            }
        });

        inProductBaseInfoMap.forEach((key, value)->{
            addProductBaseInfoList.add(value);
        });
        if (!addProductBaseInfoList.isEmpty()){
            productBaseInfoModel.insertBatch(addProductBaseInfoList);
        }
        if (!updateProductBaseInfoList.isEmpty()){
            // TODO
            productBaseInfoModel.updateBatch(updateProductBaseInfoList, corpid);
        }
        inventoryProductModel.updateMulti(productUpdateList, corpid);
//        productBaseInfoService.updateWithoutId(updateProductBaseInfoList,XbbRefTypeEnum.INVENTORY_PRODUCT.getCode(),corpid);

        List<Long> delRefIdList = new ArrayList<>();
        for (Map.Entry<Long, InventoryProductEntity> entry : orginProductMap.entrySet()) {
            InventoryProductEntity delProduct = entry.getValue();
            delRefIdList.add(delProduct.getId());
        }
        inventoryProductModel.deleteBatch(delRefIdList, corpid, DelEnum.DELETE.getDel());
        if (!delRefIdList.isEmpty()){
            productBaseInfoModel.deleteByRefIds(corpid,delRefIdList,XbbRefTypeEnum.INVENTORY_PRODUCT.getCode());
        }

    }




    /**
     * 盘点单新建时格式化解释
     *
     * @param formatExplainDTO 入参
     * @author feng.zheng
     * @date 2019/3/5 20:57
     */
    @Override
    public void formatAddExplain(FormatExplainDTO formatExplainDTO) throws XbbException {
        List<FieldAttrEntity> explainList = formatExplainDTO.getExplainList();
        String corpid = formatExplainDTO.getCorpid();
        String platForm = formatExplainDTO.getPlatform();
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            Integer fieldType = fieldAttrEntity.getFieldType();
            if (Objects.equals(fieldType, FieldTypeEnum.SELECT_PRODUCT.getType())) {
                fieldAttrEntity.setSupportScanning(BasicConstant.ONE);
                explainHelp.formatSelectProductExplains(fieldAttrEntity, XbbRefTypeEnum.INVENTORY, corpid, OperatePageEnum.NEW.getCode(), false);
                if (Objects.equals(platForm, PlatFormEnum.DINGTALK.getValue())) {
                    SaasParticularAttributePoJo saasParticularAttributePoJo = fieldAttrEntity.getSaasParticularAttributePoJo();
                    saasParticularAttributePoJo.setProductRelyAttr(InventoryEnum.WAREHOUSE_ID.getAttr());
                }
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), InventoryEnum.MANAGER_ID.getAttr())) {
                if(fieldAttrEntity.getDefaultAttr() == null || (fieldAttrEntity.getDefaultAttr() != null && fieldAttrEntity.getDefaultAttr().getDefaultList() == null)) {
                    fieldAttrEntity.setDefaultAttr(defaultAttrHelp.setUserDefaultAttrPoJo(formatExplainDTO.getUserId(), formatExplainDTO.getLoginUser().getName(),formatExplainDTO.getLoginUser().getAvatar()));
                }
            }
        }
    }

    @Override
    public InventoryDeleteBatchVO deleteBatch(InventoryDeleteBatchDTO inventoryDeleteBatchDTO) throws XbbException {
        InventoryDeleteBatchVO inventoryDeleteBatchVO = new InventoryDeleteBatchVO();
        try {
            String corpid = inventoryDeleteBatchDTO.getCorpid();
            List<Long> idList = inventoryDeleteBatchDTO.getDataIdList();
            Map<String, Object> param = BeanUtil.convertBean2Map(inventoryDeleteBatchDTO, true);
            param.put("ids", idList);
            param.put("del", DelEnum.NORMAL.getDel());
            List<InventoryEntityExt> inventoryList = inventoryModel.findEntitys(param);
            if (Objects.isNull(inventoryList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
            List<String> inventorySerialNos = new ArrayList<>();
            List<Long> inventoryIdList = new ArrayList<>();

            // 盘点单删除校验
            // 查询是否关联下游单据【其他出库单】
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder queryBuilder = boolQuery();
            queryBuilder.filter(termQuery("corpid.keyword", corpid));
            queryBuilder.filter(termQuery("data." + OutstockEnum.TYPE.getAttr(), OutstockTypeEnum.INVENTORY_OUTSTOCK.getCode()));
            queryBuilder.filter(termsQuery("data." + OutstockEnum.REF_ID.getAttr(), idList));
            queryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
            // 设置join_field
            queryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, IndexTypeEnum.IDX_SAAS_OTHER_OUTSTOCK.getType()));
            searchSourceBuilder.query(queryBuilder);
            List<PaasFormDataEntityExt> entityExts = paasEsModel.list(searchSourceBuilder, IndexTypeEnum.IDX_SAAS_OTHER_OUTSTOCK, Collections.singletonList(OutstockEnum.REF_ID.getAttr()), null, null);
            if (Objects.nonNull(entityExts) && entityExts.size() > 0) {
                entityExts.forEach(item -> {
                    Long inventoryId = item.getData().getLong(OutstockEnum.REF_ID.getAttr());
                    inventoryIdList.add(inventoryId);
                });
                for (InventoryEntityExt inventoryEntityExt : inventoryList) {
                    if (inventoryIdList.contains(inventoryEntityExt.getId())) {
                        inventorySerialNos.add(inventoryEntityExt.getSerialNo());
                    }
                }
                throw new XbbException(InstockErrorCodeEnum.API_ERROR_210030, String.format(InstockErrorCodeEnum.API_ERROR_210030.getMsg(), inventorySerialNos.toString()));
            }
            // 查询是否存在下游单据【其他入库单】
            BoolQueryBuilder boolQueryBuilder = boolQuery();
            boolQueryBuilder.filter(termQuery("data." + InstockEnum.TYPE.getAttr(), InstockTypeEnum.INVENTORY_INSTOCK.getCode()));
            boolQueryBuilder.filter(termsQuery("data." + InstockEnum.REF_ID.getAttr(), idList));
            boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
            boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
            // 设置join_field
            boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, IndexTypeEnum.IDX_SAAS_OTHER_INSTOCK.getType()));
            searchSourceBuilder.query(boolQueryBuilder);
            entityExts = paasEsModel.list(searchSourceBuilder, IndexTypeEnum.IDX_SAAS_OTHER_INSTOCK, Collections.singletonList(InstockEnum.REF_ID.getAttr()), null, null);
            if (Objects.nonNull(entityExts) && entityExts.size() > 0) {
                entityExts.forEach(item -> {
                    Long inventoryId = item.getData().getLong(InstockEnum.REF_ID.getAttr());
                    inventoryIdList.add(inventoryId);
                });
                for (InventoryEntityExt inventoryEntityExt : inventoryList) {
                    if (inventoryIdList.contains(inventoryEntityExt.getId())) {
                        inventorySerialNos.add(inventoryEntityExt.getSerialNo());
                    }
                }
                throw new XbbException(InstockErrorCodeEnum.API_ERROR_210029, String.format(InstockErrorCodeEnum.API_ERROR_210029.getMsg(), inventorySerialNos.toString()));
            }
            //查询编号
            List<String> no= new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            BoolQueryBuilder builder = boolQuery();
            // 添加corpid,formId,del
            builder.filter(termQuery("corpid.keyword", corpid));
            builder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
            builder.filter(termsQuery(StringConstant.DATA_ID, idList));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(FieldTypeEnum.SERIALNO.getAlias());
            List<PaasFormDataEntityExt> noList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_INVENTORY, builder, PaasFormDataEntityExt.class,fieldList);
            for(PaasFormDataEntityExt entityExt : noList){
                String sheetNo = entityExt.getSerialNo();
                no.add(sheetNo);
            }

            // TODO 删除权限校验
            // 因为待审批和和审批中的数据不存在表中，所以无需校验待审批和审批中的数据
            // 删除调拨单
            if(!idList.isEmpty()) {
                if(BasicConstant.ONE.equals(inventoryDeleteBatchDTO.getSingleFlag())
                        && BasicConstant.ONE.equals(idList.size())){
                    inventoryModel.deleteByKey(idList.get(0),corpid);
                }else {
                    inventoryModel.deleteBatch(idList, corpid, DelEnum.DELETE.getDel());
                }
                inventoryDeleteBatchVO.setDeleteIds(idList);
            }
            InventoryProductListDTO inventoryProductListDTO = new InventoryProductListDTO();
            BeanUtil.copyProperties(inventoryDeleteBatchDTO, inventoryProductListDTO);
            inventoryProductListDTO.setInventoryIdIn(idList);
            InventoryProductListVO inventoryProductListVO = inventoryProductService.findInventoryProductList(inventoryProductListDTO);
            if (Objects.isNull(inventoryProductListVO)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }

            // 删除关联产品
            List<Long> inventoryProductIdList = new ArrayList<>();
            inventoryProductListVO.getInventoryProductList().forEach((item) -> {
                inventoryProductIdList.add(item.getId());
            });
            if (!inventoryProductIdList.isEmpty()) {
                InventoryProductDeleteBatchDTO inventoryProductDeleteBatchDTO = new InventoryProductDeleteBatchDTO();
                BeanUtil.copyProperties(inventoryDeleteBatchDTO, inventoryProductDeleteBatchDTO);
                inventoryProductDeleteBatchDTO.setIdList(inventoryProductIdList);
                inventoryProductService.deleteBatch(inventoryProductDeleteBatchDTO);
                // 删除关联产品冗余信息
                List<Long> refIdList = inventoryProductIdList;
                ProductBaseInfoDeleteBatchDTO productBaseInfoDeleteBatchDTO = new ProductBaseInfoDeleteBatchDTO();
                BeanUtil.copyProperties(inventoryDeleteBatchDTO, productBaseInfoDeleteBatchDTO);
                productBaseInfoDeleteBatchDTO.setRefIdList(refIdList);
                productBaseInfoDeleteBatchDTO.setRefType(XbbRefTypeEnum.INVENTORY_PRODUCT.getCode());
                productBaseInfoService.deleteBatchByRefId(productBaseInfoDeleteBatchDTO);
            }
            // TODO 删除关联审批记录
            OperateTypeEnum operateTypeEnum = OperateTypeEnum.DELETE;
            if (Objects.equals(1, inventoryDeleteBatchDTO.getIsBusinessRule())) {
                operateTypeEnum = OperateTypeEnum.RULE_DELETE;
            }
            //生成删除日志(区分单个删除和批量删除)
            String userId = inventoryDeleteBatchDTO.getUserId();
            String userName = inventoryDeleteBatchDTO.getLoginUserName();
            String nameStr = StringUtils.join(no, "，");
            if(idList.size() > 1){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DELETE_FORM_DETAIL), userName, XbbRefTypeEnum.INVENTORY.getName(), idList.size());
                List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                InfoArrPojo infoArrPojo = new InfoArrPojo();
                infoArrPojo.setTitle(InventoryEnum.SHEET_NO.getAttrName());
                infoArrPojo.setContent(nameStr);
                infoArrPojoList.add(infoArrPojo);
                mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.INVENTORY, operateTypeEnum,
                        "", "", memo, inventoryDeleteBatchDTO.getHttpHeader());
            } else if (Objects.equals(idList.size(), 1)){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_WORK), userName, XbbRefTypeEnum.INVENTORY.getName(), nameStr);
                mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.INVENTORY, operateTypeEnum,
                        idList.get(0).toString(), nameStr, memo, inventoryDeleteBatchDTO.getHttpHeader());
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("inventoryServiceImpl.deleteBatch 批量删除出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return inventoryDeleteBatchVO;
    }

    @Override
    public InventoryResetInstockIdVO resetInstockIdByIdIn(InventoryResetInstockIdDTO inventoryResetInstockIdDTO) throws XbbException {
        InventoryResetInstockIdVO inventoryResetInstockIdVO = new InventoryResetInstockIdVO();
        try {
            String corpid = inventoryResetInstockIdDTO.getCorpid();
            List<UpdateDataEntity> list = new ArrayList<>();
            Map<String, Object> param = new HashMap<>();
            param.put("ids", inventoryResetInstockIdDTO.getIdIn());
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("corpid", corpid);
            List<InventoryEntityExt> inventoryList = inventoryModel.findEntitys(param);

            for (InventoryEntityExt inventoryEntityExt : inventoryList) {
                UpdateDataEntity updateDataEntity = new UpdateDataEntity();
                updateDataEntity.setCorpid(corpid);
                updateDataEntity.setId(inventoryEntityExt.getId());
                List<UpdateDataValueEntity> valueList = new ArrayList<>();
                UpdateDataValueEntity updateDataValueEntity = new UpdateDataValueEntity();
                updateDataValueEntity.setKey(InventoryEnum.INSTOCK_ID.getAttr());
                updateDataValueEntity.setEsKey(InventoryEnum.INSTOCK_ID.getAttr());
                updateDataValueEntity.setValue(0);
                valueList.add(updateDataValueEntity);
                UpdateDataValueEntity updateDataEntity1 = new UpdateDataValueEntity();
                updateDataEntity1.setKey(InventoryEnum.INVENTORY_STATUS.getAttr());
                updateDataEntity1.setEsKey(InventoryEnum.INVENTORY_STATUS.getAttr());
                updateDataEntity1.setValue(InventoryNewStatusEnum.UNFINISHED.getCode());
                valueList.add(updateDataEntity1);
                Long outstockID = FastJsonHelper.getLongOrDefaultFromFormData(inventoryEntityExt.getData(), InventoryEnum.OUTSTOCK_ID.getAttr(), 0L);
                if (Objects.equals(outstockID, 0L)) {
                    UpdateDataValueEntity updateEntity = new UpdateDataValueEntity();
                    updateEntity.setKey(InventoryEnum.STATUS.getAttr());
                    updateEntity.setEsKey(InventoryEnum.STATUS.getAttr());
                    updateEntity.setValue(1);
                    valueList.add(updateEntity);
                }
                updateDataEntity.setData(valueList);
                long now = DateUtil.getInt();
                updateDataEntity.setUpdateTime(now);
                list.add(updateDataEntity);
            }
            inventoryModel.updateBatch(list, corpid);
        } catch (Exception e) {
            LOG.error("inventoryServiceImpl.resetInstockIdByIdIn 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return inventoryResetInstockIdVO;
    }

    @Override
    public InventoryResetOutstockIdVO resetOutstockIdByIdIn(InventoryResetOutstockIdDTO inventoryResetOutstockIdDTO) throws XbbException {
        InventoryResetOutstockIdVO inventoryResetOutstockIdVO = new InventoryResetOutstockIdVO();
        try {
            String corpid = inventoryResetOutstockIdDTO.getCorpid();
            List<UpdateDataEntity> list = new ArrayList<>();
            Map<String, Object> param = new HashMap<>();
            param.put("ids", inventoryResetOutstockIdDTO.getIdIn());
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("corpid", corpid);
            List<InventoryEntityExt> inventoryList = inventoryModel.findEntitys(param);
            for (InventoryEntityExt inventoryEntityExt : inventoryList) {
                UpdateDataEntity updateDataEntity = new UpdateDataEntity();
                updateDataEntity.setCorpid(corpid);
                updateDataEntity.setId(inventoryEntityExt.getId());
                List<UpdateDataValueEntity> valueList = new ArrayList<>();
                UpdateDataValueEntity updateDataValueEntity = new UpdateDataValueEntity();
                updateDataValueEntity.setKey(InventoryEnum.OUTSTOCK_ID.getAttr());
                updateDataValueEntity.setEsKey(InventoryEnum.OUTSTOCK_ID.getAttr());
                updateDataValueEntity.setValue(0);
                valueList.add(updateDataValueEntity);
                UpdateDataValueEntity updateDataEntity1 = new UpdateDataValueEntity();
                updateDataEntity1.setKey(InventoryEnum.INVENTORY_STATUS.getAttr());
                updateDataEntity1.setEsKey(InventoryEnum.INVENTORY_STATUS.getAttr());
                updateDataEntity1.setValue(InventoryNewStatusEnum.UNFINISHED.getCode());
                valueList.add(updateDataEntity1);
                Long instockId = FastJsonHelper.getLongOrDefaultFromFormData(inventoryEntityExt.getData(), InventoryEnum.INSTOCK_ID.getAttr(), 0L);
                if (Objects.equals(instockId, 0L)) {
                    UpdateDataValueEntity updateEntity = new UpdateDataValueEntity();
                    updateEntity.setKey(InventoryEnum.STATUS.getAttr());
                    updateEntity.setEsKey(InventoryEnum.STATUS.getAttr());
                    updateEntity.setValue(1);
                    valueList.add(updateEntity);
                }
                updateDataEntity.setData(valueList);
                long now = DateUtil.getInt();
                updateDataEntity.setUpdateTime(now);
                list.add(updateDataEntity);
            }
            inventoryModel.updateBatch(list, corpid);
        } catch (Exception e) {
            LOG.error("inventoryServiceImpl.resetOutstockIdByIdIn 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return inventoryResetOutstockIdVO;
    }

//    /**
//     * 获取盘点单产品
//     *
//     * @param businessProductListDTO 入参
//     * @param jsonObject             数据对象
//     * @return 产品
//     * @throws XbbException 异常
//     */
//    @Override
//    public BusinessProductListVO getInventoryProductList(BusinessProductListDTO businessProductListDTO, JSONObject jsonObject) throws XbbException {
//        String corpid = businessProductListDTO.getCorpid();
//        String userId = businessProductListDTO.getUserId();
//        UserEntity userEntity = userModel.getByKey(userId, corpid);
//        Long inventoryId = businessProductListDTO.getDataId();
//        boolean detailGet = businessProductListDTO.getDetailGet();
//        Integer fromInstock = businessProductListDTO.getFromInstock();
//        Integer fromOutstock = businessProductListDTO.getFromOutstock();
//        boolean isInstock = Objects.equals(fromInstock, 1);
//        boolean isOutstock = Objects.equals(fromOutstock, 1);
//        boolean generalGetProduct = !isInstock && !isOutstock;
//
//        JSONObject inventoryDataList;
//        List<InventoryProductEntity> inventoryProducts = new ArrayList<>();
//        // 盘点单产品冗余信息
//        List<ProductBaseInfoEntity> productBaseInfoList = new ArrayList<>();
//        // 流程数据没有inventoryId，需要重新组装inventoryProducts，productBaseInfoList
//        Map<String, Object> modelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//        modelMap.put(ParameterConstant.PAGE, businessProductListDTO.getPage());
//        modelMap.put(ParameterConstant.CORPID, corpid);
//        modelMap.put("inventoryId", inventoryId);
//        modelMap.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
//        PageHelper pageHelper = PageHelperUtil.getPageHelper(modelMap, inventoryProductModel, businessProductListDTO.getPageSize());
//        if (businessProductListDTO.getForProcess()) {
//            inventoryDataList = jsonObject;
//            JSONArray productArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(saasUpdateHelp.getJsonObjectOrDefaultFromFormData(jsonObject, InventoryEnum.PRODUCT.getAttr(), new JSONObject()), StringConstant.PRODUCT_LIST, new JSONArray());
//            Map<Long, ProductEntityExt> productMap = getProductMap(new HashSet<>(), corpid, productArray);
//            formatProductList(corpid, inventoryProducts, productBaseInfoList, jsonObject, productMap);
//        } else {
//            InventoryEntityExt inventoryEntity = inventoryModel.getByKey(inventoryId, corpid);
//            inventoryDataList = inventoryEntity.getData();
//            // 获取盘点单关联产品
//            inventoryProducts = (List<InventoryProductEntity>)PageHelperUtil.getEntityList(modelMap, pageHelper, inventoryProductModel);
//            List<Long> productIdIn = new ArrayList<>();
//            for (InventoryProductEntity inventoryProductEntity : inventoryProducts) {
//                productIdIn.add(inventoryProductEntity.getProductId());
//            }
//            Map<Long, ProductEntityExt> productMap = productModel.getProductMapByIdIn(corpid, productIdIn, null);
//            for (InventoryProductEntity inventoryProductEntity : inventoryProducts) {
//                ProductEntityExt productEntityExt = productMap.get(inventoryProductEntity.getProductId());
//                if (Objects.nonNull(productEntityExt)) {
//                    String childSpecification = productEntityExt.getData().getString(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr());
//                    String barcode = FastJsonHelper.getStringOrDefaultFromFormData(productEntityExt.getData(), ProductEnum.BARCODE.getAttr(), "");
//                    inventoryProductEntity.setBarcode(barcode);
//                    inventoryProductEntity.setProductSpecification(childSpecification);
//                }
//            }
//        }
//        Long warehouseId = FastJsonHelper.getLongOrDefaultFromFormData(inventoryDataList, InventoryEnum.WAREHOUSE_ID.getAttr(), 0L);
//        List<Long> productIds = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//        productIds.add(-1L);
//        List<Long> inventoryProductIds = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//        inventoryProductIds.add(-1L);
//        List<Long> warehouseIds = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//        warehouseIds.add(-1L);
//        for (InventoryProductEntity entity : inventoryProducts) {
//            productIds.add(entity.getProductId());
//            inventoryProductIds.add(entity.getId());
//            warehouseIds.add(entity.getWarehouseId());
//        }
//        // 根据productIdIn获取对应产品信息
//        Map<Long, ProductEntityExt> productMap = productModel.getProductMapByIdIn(corpid, productIds, null);
//        // 出入库选择盘点单时，要获取产品所在的仓库信息
//        Map<Long, JSONObject> inventoryProductWarehouseMap = null;
//        if (isInstock || isOutstock) {
//            inventoryProductWarehouseMap = warehouseModel.findWarehouseObjMapByIdIn(warehouseIds, corpid);
//        }
//        // 需要查询的字段
//        List<String> fieldList = Arrays.asList("productId", "num", "cost");
//        // 盘点产品分仓库存
//        Map<Long, ProductWarehouseEntity> warehouseMap = productWarehouseModel.getWarehouseProductList(corpid, warehouseId, productIds, fieldList);
//
//        if (!businessProductListDTO.getForProcess()) {
//            productBaseInfoList = productBaseInfoModel.getProductBaseInfoList(corpid, XbbRefTypeEnum.INVENTORY_PRODUCT.getCode(), inventoryProductIds);
//        }
//
//        Map<Long, ProductBaseInfoEntity> baseInfoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//        for (ProductBaseInfoEntity productBaseInfoEntity : productBaseInfoList) {
//            baseInfoMap.put(productBaseInfoEntity.getRefId(), productBaseInfoEntity);
//        }
//        // 用于存放当前启用的产品模板解释的map
//        Map<String, FieldAttrEntity> nowProductExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//        Map<String, FieldAttrEntity> nowStockProductExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//        saasAddHelp.getRelativeProductExplainsFromDB(corpid, nowProductExplainMap, nowStockProductExplainMap);
//
//        // 参数集合
//        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//
//        // 返回给前端的接受对象
//        JSONObject productFinalObj = new JSONObject();
//        JSONArray productArray = new JSONArray();
//        Map<Integer, JSONObject> productSortMap = new TreeMap<>();
//        BusinessProductListVO businessProductListVO = new BusinessProductListVO();
//        // 与productList同级，返回对应关联产品的attr
//        String attrStr = "";
//
//        if (isInstock) {
//            attrStr = InstockEnum.PRODUCT.getAttr();
//            // 盘盈入库选择盘点单产品
//            for (InventoryProductEntity inventoryProduct : inventoryProducts) {
//                if (inventoryProduct.getProductNum() <= inventoryProduct.getOriNum()) {
//                    // 没有盘盈
//                    continue;
//                }
//                Long productId = inventoryProduct.getProductId();
//                Long inventoryProductId = inventoryProduct.getId();
//
//                InstockProductEntityExt instockProductExt = new InstockProductEntityExt();
//                instockProductExt.setParentId(inventoryProduct.getParentId());
//                instockProductExt.setProductId(productId);
//                instockProductExt.setProductName(inventoryProduct.getProductName());
//                instockProductExt.setProductNo(inventoryProduct.getProductNo());
//                // 格式化规格
//                String specification = specificationModel.joinSpecification(inventoryProduct.getProductSpecification());
//                instockProductExt.setProductSpecification(specification);
//                instockProductExt.setProductUnit(inventoryProduct.getProductUnit());
//                // 盘盈的入库数量是inventoryProduct.getProductNum()-inventoryProduct.getOriNum()
//                Double differNum = Arith.sub(inventoryProduct.getProductNum(), inventoryProduct.getOriNum());
//                instockProductExt.setProductNum(differNum);
//                instockProductExt.setWarehouseId(inventoryProduct.getWarehouseId());
//                // 设置仓库信息
//                if (inventoryProduct.getWarehouseId() != null) {
//                    JSONObject warehouseObj = inventoryProductWarehouseMap.get(inventoryProduct.getWarehouseId());
//                    instockProductExt.setWarehouseObj(warehouseObj);
//                }
//
//                Double productStock = 0.0;
//                String batch = "";
//                Double productCost = 0D;
//
//                // 获取对应的产品信息
//                ProductEntityExt product = productMap.get(inventoryProduct.getProductId());
//                if (product != null) {
//                    JSONObject productDataList = product.getData();
//                    instockProductExt.setBarcode(productDataList.getString(ProductEnum.BARCODE.getAttr()));
//                    // 产品的平均成本
//                    productCost = productDataList.getDouble(ProductEnum.COST.getAttr());
//                    // 产品的总库存
//                    productStock = productDataList.getDouble(ProductEnum.STOCK.getAttr());
//                    // 产品图片
//                    instockProductExt.setImageUrlArray(productDataList.getJSONArray(ProductEnum.PRODUCT_IMGS.getAttr()));
//                }
//                ProductBaseInfoEntity productBaseInfo = baseInfoMap.get(inventoryProductId);
//                if (productBaseInfo == null) {
//                    ProductWarehouseEntity productWarehouse = warehouseMap.get(productId);
//                    if (productWarehouse != null) {
//                        productStock = productWarehouse.getNum();
//                        // 产品仓库成本
//                        productCost = productWarehouse.getCost();
//                    }
//                } else {
//                    batch = productBaseInfo.getBatch();
//                    // 判断有没有批次信息
//                    if (StringUtil.isNotEmpty(batch)) {
//                        // 获取该批次产品在当前仓库下的库存
//                        params.clear();
//                        params.put("corpid", corpid);
//                        params.put("del", 0);
//                        params.put("productId", productId);
//                        params.put("warehouseId", inventoryProduct.getWarehouseId());
//                        params.put("batch", batch);
//                        List<ProductStockEntity> productStockEntityList = productStockModel.getValidBatchInfoList(Collections.singletonList(productId),corpid,inventoryProduct.getWarehouseId(),batch, Arrays.asList("num", "cost"));
//                        Double sum = 0D;
//                        Double num = 0D;
//                        for (ProductStockEntity stockInfo : productStockEntityList) {
//                            if (stockInfo.getNum() != null) {
//                                sum += stockInfo.getCost() * stockInfo.getNum();
//                                num += stockInfo.getNum();
//                                // TODO 是显示批次库存吗？
//                            }
//                        }
//                        productStock = num;
//                        if (num != 0D) {
//                            // 批次成本
//                            productCost = Arith.div(sum, num);
//                        }
//                    } else {
//                        ProductWarehouseEntity productWarehouse = warehouseMap.get(productId);
//                        if (productWarehouse != null) {
//                            productStock = productWarehouse.getNum();
//                            // 产品仓库成本
//                            productCost = productWarehouse.getCost();
//                        }
//                    }
//                    instockProductExt.setBatch(batch);
//                    instockProductExt.setProduceDate(productBaseInfo.getProduceDate());
//                    instockProductExt.setGuaranteePeriod(productBaseInfo.getGuaranteePeriod());
//                    instockProductExt.setMemo(productBaseInfo.getMemo());
//                }
//                instockProductExt.setCost(productCost);
//                instockProductExt.setStock(productStock);
//
//                // 构建格式化入库产品的DTO
//                FormatInstockProductDTO formatInstockProductDTO = new FormatInstockProductDTO();
//                BeanUtil.copyProperties(businessProductListDTO, formatInstockProductDTO);
//                formatInstockProductDTO.setCorpid(corpid);
//                formatInstockProductDTO.setUserEntity(userEntity);
//                if (productBaseInfo != null) {
//                    ProductStockInfoEntity productStockInfoEntity = new ProductStockInfoEntity();
//                    BeanUtil.copyProperties(productBaseInfo, productStockInfoEntity);
//                    instockProductExt.setProductStockInfoEntity(productStockInfoEntity);
//                }
//                formatInstockProductDTO.setInstockProductExt(instockProductExt);
//                formatInstockProductDTO.setNowProductExplainMap(nowProductExplainMap);
//                formatInstockProductDTO.setNowStockProductExplainMap(nowStockProductExplainMap);
//                JSONObject productObj = instockService.getFormatProductJsonArray(formatInstockProductDTO);
//
//                productSortMap.put(inventoryProduct.getSort(), productObj);
//            }
//        }
//        if (isOutstock) {
//            attrStr = OutstockEnum.PRODUCT.getAttr();
//            // 盘亏出库选择盘点单产品
//            for (InventoryProductEntity inventoryProduct : inventoryProducts) {
//                if (inventoryProduct.getProductNum() > inventoryProduct.getOriNum()) {
//                    // 没有盘亏
//                    continue;
//                }
//
//                Long inventoryProductId = inventoryProduct.getId();
//                String productName = inventoryProduct.getProductName();
//                Long productId = inventoryProduct.getProductId();
//
//                OutstockProductEntityExt outstockProductExt = new OutstockProductEntityExt();
//                outstockProductExt.setParentId(inventoryProduct.getParentId());
//                outstockProductExt.setProductId(productId);
//                outstockProductExt.setProductName(productName);
//                outstockProductExt.setProductNo(inventoryProduct.getProductNo());
//                String specification = inventoryProduct.getProductSpecification();
//                outstockProductExt.setProductSpecification(specificationModel.joinSpecification(specification));
//                outstockProductExt.setProductUnit(inventoryProduct.getProductUnit());
//                // 盘亏的出库数量是inventoryProduct.getOriNum()-inventoryProduct.getProductNum()
//                Double differNum = Arith.sub(inventoryProduct.getOriNum(), inventoryProduct.getProductNum());
//                outstockProductExt.setProductNum(differNum);
//                outstockProductExt.setWarehouseId(inventoryProduct.getWarehouseId());
//                // 设置仓库信息
//                if (inventoryProduct.getWarehouseId() != null) {
//                    JSONObject warehouseObj = inventoryProductWarehouseMap.get(inventoryProduct.getWarehouseId());
//                    outstockProductExt.setWarehouseObj(warehouseObj);
//                }
//
//                Double productStock = 0.0;
//                String batch = "";
//                Double productCost = 0D;
//
//                ProductEntityExt product = productMap.get(productId);
//                if (product != null) {
//                    JSONObject productDataList = product.getData();
//                    outstockProductExt.setBarcode(productDataList.getString(ProductEnum.BARCODE.getAttr()));
//                    // 获取关联产品的产品平均成本作为出库成本
//                    productCost = productDataList.getDouble(ProductEnum.COST.getAttr());
//                    // 产品的总库存
//                    productStock = productDataList.getDouble(ProductEnum.STOCK.getAttr());
//                    // 产品图片
//                    outstockProductExt.setImageUrlArray(productDataList.getJSONArray(ProductEnum.PRODUCT_IMGS.getAttr()));
//                }
//                ProductBaseInfoEntity productBaseInfo = baseInfoMap.get(inventoryProductId);
//                if (productBaseInfo == null) {
//                    ProductWarehouseEntity productWarehouse = warehouseMap.get(productId);
//                    // 选择了仓库
//                    if (productWarehouse != null) {
//                        // 产品的仓库库存
//                        productStock = productWarehouse.getNum();
//                        // 产品仓库成本
//                        productCost = productWarehouse.getCost();
//                    }
//                } else {
//                    batch = productBaseInfo.getBatch();
//                    // 选择了批次
//                    if (StringUtil.isNotEmpty(batch)) {
//                        // 获取该批次产品在当前仓库下的库存
//                        params.clear();
//                        params.put("corpid", corpid);
//                        params.put("del", 0);
//                        params.put("productId", productId);
//                        params.put("warehouseId", inventoryProduct.getWarehouseId());
//                        params.put("batch", batch);
//                        List<ProductStockEntity> productStockEntityList = productStockModel.getValidBatchInfoList(Collections.singletonList(productId),corpid,inventoryProduct.getWarehouseId(),batch, Arrays.asList("num", "cost"));
//                        Double sum = 0D;
//                        Double num = 0D;
//                        for (ProductStockEntity stockInfo : productStockEntityList) {
//                            if (stockInfo.getNum() != null) {
//                                sum += stockInfo.getCost() * stockInfo.getNum();
//                                num += stockInfo.getNum();
//                                // TODO 是显示批次库存吗？
//                            }
//                        }
//                        if (num != 0D) {
//                            // 批次成本
//                            productCost = Arith.div(sum, num);
//                        }
//                    } else {
//                        ProductWarehouseEntity productWarehouse = warehouseMap.get(productId);
//                        if (productWarehouse != null) {
//                            // 产品的仓库库存
//                            productStock = productWarehouse.getNum();
//                            // 产品仓库成本
//                            productCost = productWarehouse.getCost();
//                        }
//                    }
//                    outstockProductExt.setBatch(batch);
//                    outstockProductExt.setProduceDate(productBaseInfo.getProduceDate());
//                    outstockProductExt.setGuaranteePeriod(productBaseInfo.getGuaranteePeriod());
//                    outstockProductExt.setMemo(productBaseInfo.getMemo());
//                }
//                outstockProductExt.setCost(productCost);
//                outstockProductExt.setStock(productStock);
//                // 构建格式化出库产品的DTO
//                FormatOutstockProductDTO formatOutstockProductDTO = new FormatOutstockProductDTO();
//                BeanUtil.copyProperties(businessProductListDTO, formatOutstockProductDTO);
//                formatOutstockProductDTO.setCorpid(corpid);
//                formatOutstockProductDTO.setUserEntity(userEntity);
//                if (productBaseInfo != null) {
//                    ProductStockInfoEntity productStockInfoEntity = new ProductStockInfoEntity();
//                    BeanUtil.copyProperties(productBaseInfo, productStockInfoEntity);
//                    outstockProductExt.setProductStockInfoEntity(productStockInfoEntity);
//                }
//                formatOutstockProductDTO.setOutstockProductExt(outstockProductExt);
//                formatOutstockProductDTO.setNowProductExplainMap(nowProductExplainMap);
//                formatOutstockProductDTO.setNowStockProductExplainMap(nowStockProductExplainMap);
//
//                JSONObject productObj = outstockService.getFormatProductJsonArray(formatOutstockProductDTO);
//                productSortMap.put(inventoryProduct.getSort(), productObj);
//            }
//        }
//        if (generalGetProduct) {
//            attrStr = InventoryEnum.PRODUCT.getAttr();
//            // 正常获取盘点单产品
//            for (InventoryProductEntity inventoryProduct : inventoryProducts) {
//                Long productId = inventoryProduct.getProductId();
//                Long inventoryProductId = inventoryProduct.getId();
//
//                InventoryProductEntityExt inventoryProductExt = new InventoryProductEntityExt();
//                BeanUtil.copyProperties(inventoryProduct, inventoryProductExt);
//
//                Double productStock = 0D;
//                String batch;
//                ProductBaseInfoEntity productBaseInfo = baseInfoMap.get(inventoryProductId);
//                if (productBaseInfo == null) {
//                    ProductWarehouseEntity productWarehouse = warehouseMap.get(productId);
//                    if (productWarehouse != null) {
//                        // 产品仓库库存
//                        productStock = productWarehouse.getNum();
//                    }
//                } else {
//                    batch = productBaseInfo.getBatch();
//                    // 判断有没有批次信息
//                    if (StringUtil.isNotEmpty(batch)) {
//                        // 获取该批次产品在当前仓库下的库存
//                        params.clear();
//                        params.put("corpid", corpid);
//                        params.put("del", 0);
//                        params.put("productId", productId);
//                        params.put("warehouseId", inventoryProductExt.getWarehouseId());
//                        params.put("batch", batch);
////                        List<ProductStockInfoEntity> productStockList = productStockInfoService.getValidBatchInfoList(corpid, params);
//                        List<ProductStockEntity> productStockEntityList = productStockModel.getValidBatchInfoList(Collections.singletonList(productId),corpid,inventoryProduct.getWarehouseId(),batch, Arrays.asList("num"));
//                        for (ProductStockEntity stockInfo : productStockEntityList) {
//                            if (stockInfo.getNum() != null) {
//                                productStock += stockInfo.getNum();
//                            }
//                        }
//                    } else {
//                        ProductWarehouseEntity productWarehouse = warehouseMap.get(productId);
//                        if (productWarehouse != null) {
//                            // 产品仓库库存
//                            productStock = productWarehouse.getNum();
//                        }
//                    }
//                }
//                ProductEntityExt product = productMap.get(productId);
//                if (product != null) {
//                    JSONObject productData = product.getData();
//                    if (productData != null) {
//                        inventoryProductExt.setImageUrlArray(productData.getJSONArray(ProductEnum.PRODUCT_IMGS.getAttr()));
//                    }
//                }
//                inventoryProductExt.setStock(productStock);
//                inventoryProductExt.setProductSpecification(specificationModel.joinSpecification(inventoryProduct.getProductSpecification()));
//                // 构建格式化盘点产品的DTO
//                FormatInventoryProductDTO formatInventoryProductDTO = new FormatInventoryProductDTO();
//                BeanUtil.copyProperties(businessProductListDTO, formatInventoryProductDTO);
//                formatInventoryProductDTO.setCorpid(corpid);
//                inventoryProductExt.setProductBaseInfoEntity(productBaseInfo);
//                formatInventoryProductDTO.setInventoryProductExt(inventoryProductExt);
//                formatInventoryProductDTO.setNowProductExplainMap(nowProductExplainMap);
//                formatInventoryProductDTO.setNowStockProductExplainMap(nowStockProductExplainMap);
//                JSONObject productObj = getFormatProductJsonArray(formatInventoryProductDTO, generalGetProduct, detailGet);
//                productSortMap.put(inventoryProductExt.getSort(), productObj);
//            }
//        }
//        // 产品排序
//        productArray.addAll(productSortMap.values());
//        productFinalObj.put(StringConstant.PRODUCT_LIST, productArray);
//        productFinalObj.put(StringConstant.REDUNDANT_FIELD_ATTR_BEGIN_FLAG, attrStr);
//        if (generalGetProduct && detailGet) {
//            // 普通获取产品并且是详情时，增加表头解释
//            List<FieldAttrEntityExt> fieldAttrEntityList = saasUpdateHelp.getSelectProductExplains(XbbRefTypeEnum.INVENTORY, corpid, InventoryEnum.PRODUCT.getAttr());
//            for (int i=0; i<fieldAttrEntityList.size(); i++) {
//                FieldAttrEntityExt fieldAttr = fieldAttrEntityList.get(i);
//                if (Objects.equals(fieldAttr.getAttr(), STOCK.getSaasAttr())) {
//                    FieldAttrEntityExt fieldAttrEntity = new FieldAttrEntityExt();
//                    BeanUtil.copyProperties(PROFIT_STATUS, fieldAttrEntity);
//                    // 在库存数量字段的后面添加盈亏状态
//                    fieldAttrEntityList.add(i+1, fieldAttrEntity);
//                    break;
//                }
//            }
//            // fix：12421 【web-盘点单】产品信息tab页中：盘亏数量显示错误
//            fieldAttrEntityList.removeIf(fieldAttr -> Objects.equals(fieldAttr.getAttr(), STOCK.getSaasAttr()));
//            productFinalObj.put(BusinessConstant.EXPLAINS, fieldAttrEntityList);
//        }
//        businessProductListVO.setProduct(productFinalObj);
//        businessProductListVO.setPageHelper(pageHelper);
//        return businessProductListVO;
//    }

    /**
     * 获取格式化的产品
     *
     * @param formatInventoryProductDTO 格式化盘点单产品的DTO
     * @return 产品对象
     * @throws XbbException 异常
     */
    @Override
    public JSONObject getFormatProductJsonArray(FormatInventoryProductDTO formatInventoryProductDTO, boolean generalGetProduct, boolean detailGet) throws XbbException {
        // 获取参数
        InventoryProductEntityExt inventoryProductExt = formatInventoryProductDTO.getInventoryProductExt();
        Map<String, FieldAttrEntity> nowProductExplainMap = formatInventoryProductDTO.getNowProductExplainMap();
        ProductBaseInfoEntity productBaseInfo = inventoryProductExt.getProductBaseInfoEntity();
        if (productBaseInfo == null) {
            productBaseInfo = new ProductBaseInfoEntity();
        }
        JSONArray attrArray = new JSONArray();
        JSONObject productObj = new JSONObject();
        // 获取关联产品需要展示的字段
        BusinessProductEnum businessProductEnum = BusinessProductEnum.getByCodeAndTargetCode(XbbRefTypeEnum.INVENTORY.getCode(),XbbRefTypeEnum.INVENTORY.getCode());
        List<RelativeProductEnum> businessProductEnumList = new ArrayList<>(businessProductEnum.getList());

        // 普通获取产品并且是详情时 在库存数量字段的后面添加盈亏状态
        if (generalGetProduct && detailGet) {
            for (int i = 0; i < businessProductEnumList.size(); i++) {
                RelativeProductEnum relativeProductEnum = businessProductEnumList.get(i);
                if (Objects.equals(relativeProductEnum, STOCK)) {
                    businessProductEnumList.add(i + 1, PROFIT_STATUS);
                    break;
                }
            }
            // fix：12421 【web-盘点单】产品信息tab页中：盘亏数量显示错误
            businessProductEnumList.removeIf(fieldAttr -> Objects.equals(fieldAttr, STOCK));
        }

        for (RelativeProductEnum productEnum : businessProductEnumList) {
            String saasAttr = productEnum.getSaasAttr();
            FieldAttrEntity fieldAttrEntity = null;
            if (nowProductExplainMap.containsKey(saasAttr)) {
                fieldAttrEntity = nowProductExplainMap.get(saasAttr);
            }
            switch (productEnum) {
                case NAME:
                    JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(NAME, inventoryProductExt.getProductName(), fieldAttrEntity));
                    break;
                case PRODUCT_NO:
                    JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(PRODUCT_NO, inventoryProductExt.getProductNo(), fieldAttrEntity));
                    break;
                case BARCODE:
                    JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(BARCODE, inventoryProductExt.getBarcode(), fieldAttrEntity));
                    break;
                case NUM:
                    if(Objects.isNull(fieldAttrEntity)) {
                        fieldAttrEntity = new FieldAttrEntity();
                    }
                    FieldAttrEntity stockAttrEntity = nowProductExplainMap.get(ProductEnum.STOCK.getSaasAttr());
                    if(Objects.nonNull(stockAttrEntity)) {
                        fieldAttrEntity.setAccuracy(stockAttrEntity.getAccuracy());
                    }
                    JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(NUM, inventoryProductExt.getProductNum(), fieldAttrEntity));
                    break;
                case PROFIT_STATUS:
                    String attrValue = "";
                    double leftNum = Arith.sub(inventoryProductExt.getOriNum(), inventoryProductExt.getProductNum());
                    if (leftNum > 0) {
                        attrValue = attrValue + I18nMessageUtil.getMessage(I18nStringConstant.INVENTORY_LOSSES) + "：" + leftNum;
                    }
                    if (leftNum < 0) {
                        attrValue = attrValue + I18nMessageUtil.getMessage(I18nStringConstant.INVENTORY_SURPLUS) + "：" + Math.abs(leftNum);
                    }
                    JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(PROFIT_STATUS, attrValue, fieldAttrEntity));
                    break;
                case STOCK:
                    JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(STOCK, inventoryProductExt.getStock(), fieldAttrEntity));
                    break;
                case UNIT:
                    // 单位回显 存的key是0,1,2 回显对应的单位
                    String productUnit = inventoryProductExt.getProductUnit();
                    String unitStr = productModel.getProductUnitTextByValue(productUnit, fieldAttrEntity);
                    JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(UNIT, unitStr, fieldAttrEntity));
                    break;
                case SPECIFICATION:
                    // 格式化规格
                    String specification = specificationModel.joinSpecification(inventoryProductExt.getProductSpecification());
                    JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(SPECIFICATION, specification, fieldAttrEntity));
                    break;
                case BATCH:
                    JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(BATCH, productBaseInfo.getBatch(), fieldAttrEntity));
                    break;
                case GUARANTEE_PERIOD:
                    Double period = productBaseInfo.getGuaranteePeriod() == null ? 0D : productBaseInfo.getGuaranteePeriod() / (double) 86400;
                    JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(GUARANTEE_PERIOD, period, fieldAttrEntity));
                    break;
                case PRODUCE_DATE:
                    Long productDate = productBaseInfo.getProduceDate();
                    String date = productDate == null ? "" : DateTimeUtil.getStringEpochSecond(productDate, DateTimeUtil.SDFDate);
                    JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(PRODUCE_DATE, date, fieldAttrEntity));
                    break;
                case MEMO:
                    JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(MEMO, Objects.toString(productBaseInfo.getMemo(), ""), fieldAttrEntity));
                    break;
                case THUMBNAIL:
                    JSONArray defaultImage = new JSONArray(Collections.singletonList(StringConstant.DEFAULT_IMAGES));
                    JSONArray imageList = inventoryProductExt.getImageUrlArray() == null ? defaultImage : inventoryProductExt.getImageUrlArray();
                    productObj.put(ProductEnum.THUMBNAIL.getSaasAttr(), imageList);
                    break;
                default:
                    break;
            }
        }
        productObj.put("result", attrArray);
        productObj.put(StringConstant.SAAS_LINK_BUSINESS_ID, inventoryProductExt.getProductId());
        productObj.put(StringConstant.BUSINESS_PRODUCT_ID, inventoryProductExt.getId());
        productObj.put("parentId", inventoryProductExt.getParentId());
        // TODO 库存产品自定义字段的回显
        return productObj;
    }

//    /**
//     * 格式化盘点单产品，显示给前端
//     *
//     * @param dataList            盘点单实体数据
//     * @param saasAnalysisDataDTO 数据解析DTO
//     * @author feng.zheng
//     * @date 2019-02-01 15:19
//     */
//    @Override
//    public void formatProduct4Show(JSONObject dataList, SaasAnalysisDataDTO saasAnalysisDataDTO) throws XbbException {
//        if (dataList == null || saasAnalysisDataDTO == null) {
//            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028);
//        }
//        // 盘点单关联产品
//        BusinessProductListDTO businessProductListDTO = new BusinessProductListDTO();
//        BeanUtil.copyProperties(saasAnalysisDataDTO, businessProductListDTO);
//        BusinessProductListVO businessProductListVO;
//        if (saasAnalysisDataDTO.getForProcess()) {
//            businessProductListVO = getInventoryProductList(businessProductListDTO, dataList);
//        } else {
//            businessProductListVO = getInventoryProductList(businessProductListDTO, null);
//        }
//        JSONObject productFinalObj = businessProductListVO.getProduct();
//        dataList.put(InventoryEnum.PRODUCT.getAttr(), productFinalObj);
//    }

    @Override
    public PagingProductVO getPagingProduct(PagingProductDTO pagingProductDTO) throws XbbException {
        PagingProductVO pagingProductVO = new PagingProductVO();
        Map<String, Object> modelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        modelMap.put(ParameterConstant.CORPID, pagingProductDTO.getCorpid());
        modelMap.put(ParameterConstant.INVENTORY_ID, pagingProductDTO.getDataId());
        modelMap.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        modelMap.put(ParameterConstant.PAGE,  pagingProductDTO.getPage());
        modelMap.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
        PageHelper pageHelper = PageHelperUtil.getPageHelper(modelMap, inventoryProductModel, pagingProductDTO.getPageSize());
        List<InventoryProductEntity> inventoryProductEntityList = (List<InventoryProductEntity>) PageHelperUtil.getEntityList(modelMap, pageHelper, inventoryProductModel);
        if (pagingProductDTO.getUpdateDataTypeEnum().isDetail()) {
            DetailProductVO detailProductVO = formatProduct4DetailShow(inventoryProductEntityList, pagingProductDTO);
            pagingProductVO.setProductDataArr(detailProductVO.getProductDataArr());
        }
        pagingProductVO.setPageHelper(pageHelper);
        return pagingProductVO;
    }

    @Override
    public DetailProductVO formatProduct4DetailShow(List<InventoryProductEntity> inventoryProductEntityList, PagingProductDTO pagingProductDTO) throws XbbException{
        DetailProductVO detailProductVO = new DetailProductVO();
        Set<Long> productIds = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Set<Long> inventoryProductIdSet = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (InventoryProductEntity inventoryProductEntity : inventoryProductEntityList) {
            productIds.add(inventoryProductEntity.getProductId());
            inventoryProductIdSet.add(inventoryProductEntity.getId());
        }
        String corpid = pagingProductDTO.getCorpid();
        JSONArray productArray = new JSONArray();
        Map<Long, PaasFormDataEntityExt> productMap = productService.getProductMapByIdIn(productIds, corpid, DelEnum.NORMAL);
        List<ProductBaseInfoEntity> productBaseInfoList = productBaseInfoModel.getProductBaseInfoList(corpid, XbbRefTypeEnum.INVENTORY_PRODUCT.getCode(), inventoryProductIdSet);
        Map<Long, ProductBaseInfoEntity> baseInfoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (ProductBaseInfoEntity productBaseInfoEntity : productBaseInfoList) {
            baseInfoMap.put(productBaseInfoEntity.getRefId(), productBaseInfoEntity);
        }
        PaasFormExplainEntity productExplains = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(), corpid);
        if (Objects.isNull(productExplains)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        Map<String, FieldAttrEntity> productExplainMap = ExplainUtil.getExplainMap(productExplains.getExplains(), null);
        for (InventoryProductEntity inventoryProductEntity : inventoryProductEntityList) {
            PaasFormDataEntityExt paasFormDataEntityExt = productMap.get(inventoryProductEntity.getProductId());
            ProductBaseInfoEntity productBaseInfoEntity = baseInfoMap.getOrDefault(inventoryProductEntity.getId(), new ProductBaseInfoEntity());
            JSONObject json = new JSONObject();
            if (Objects.nonNull(inventoryProductEntity.getData())) {
                json = inventoryProductEntity.getData();
            }
            for (InventoryProductEnum inventoryProductEnum : InventoryProductEnum.values()) {
                if (!UpdateDataTypeEnum.DETAIL.formatShow(inventoryProductEnum.getShowType())) {
                    continue;
                }
                String attr = inventoryProductEnum.getAttr();
                switch (inventoryProductEnum) {
                    case PRODUCT:
                        json.put(attr, inventoryProductEntity.getProductId());
                        break;
                    case NUM:
                        json.put(attr, inventoryProductEntity.getProductNum());
                        break;
                    case STOCK:
                        json.put(attr, inventoryProductEntity.getOriNum());
                        break;
                    case MEMO:
                        json.put(attr, StringUtil.isNotEmpty(productBaseInfoEntity.getMemo()) ? productBaseInfoEntity.getMemo():inventoryProductEntity.getMemo());
                        break;
                   /* case BATCH:
                        json.put(attr, productBaseInfoEntity.getBatch());
                        break;
                    case PRODUCE_DATE:
                        if (Objects.nonNull(productBaseInfoEntity.getProduceDate())){
                            json.put(attr, productBaseInfoEntity.getProduceDate());
                        }
                        break;
                    case GUARANTEE_PERIOD:
                        if (Objects.nonNull(productBaseInfoEntity.getGuaranteePeriod()) && !Objects.equals(productBaseInfoEntity.getProduceDate(), 0L)) {
                            json.put(attr, Arith.div(productBaseInfoEntity.getGuaranteePeriod(), 86400D));
                        }
                        break;
                    case EXPIRE_DATE:
                        if (Objects.nonNull(productBaseInfoEntity.getGuaranteePeriod()) && Objects.nonNull(productBaseInfoEntity.getProduceDate())) {
                            json.put(attr, Arith.add(productBaseInfoEntity.getProduceDate(), productBaseInfoEntity.getGuaranteePeriod()));
                        }
                        break;*/
                    case UNIT:
                        if (Objects.nonNull(inventoryProductEntity.getProductUnit())) {
                            json.put(attr, productModel.getProductUnitTextByValue(json.getString(ProductEnum.UNIT.getAttr()), productExplainMap.get(ProductEnum.UNIT.getAttr())));
                        }else if (Objects.nonNull(paasFormDataEntityExt)) {
                            json.put(attr,  productModel.getProductUnitTextByValue(FastJsonHelper.getStringOrDefaultFromFormData(paasFormDataEntityExt.getData(), ProductEnum.UNIT.getAttr(), ""), productExplainMap.get(ProductEnum.UNIT.getAttr())));
                        }
                        break;
                    case INVENTORY:
                        String attrValue = "";
                        double leftNum = Arith.sub(inventoryProductEntity.getOriNum(), inventoryProductEntity.getProductNum());
                        if (leftNum > 0) {
                            attrValue = attrValue + I18nMessageUtil.getMessage(I18nStringConstant.INVENTORY_LOSSES) + "：" + leftNum;
                            json.put(StringConstant.RED_FLAG, 1);
                        }
                        if (leftNum < 0) {
                            attrValue = attrValue + I18nMessageUtil.getMessage(I18nStringConstant.INVENTORY_SURPLUS) + "：" + Math.abs(leftNum);
                            json.put(StringConstant.RED_FLAG, 1);
                        }
                        json.put(attr, attrValue);
                        break;
                    default:
                        break;
                }
            }
            if (Objects.equals(json.getDouble(SelectProductEnum.GUARANTEE_PERIOD.getAttr()), 0D)) {
                if (Objects.equals(json.getLong(SelectProductEnum.PRODUCE_DATE.getAttr()), 0L) || Objects.isNull(json.get(SelectProductEnum.PRODUCE_DATE.getAttr()))) {
                    json.remove(SelectProductEnum.GUARANTEE_PERIOD.getAttr());
                }
            }
            json.put(BusinessConstant.PRODUCT_SUB_ID, inventoryProductEntity.getId());
            productArray.add(json);
        }
        detailProductVO.setProductDataArr(productArray);
        return detailProductVO;
    }

    @Override
    public void formatProduct4Show2(Long dataId, String corpid, JSONObject data, UpdateDataTypeEnum updateDataTypeEnum) throws XbbException {
        inventoryModel.formatProduct4Show2(dataId, corpid, data, updateDataTypeEnum);
    }

    @Override
    public JSONObject formatSingleProduct(InventoryProductEntity inventoryProductEntity,ProductBaseInfoEntity productBaseInfoEntity) {
        return inventoryModel.formatSingleProduct(inventoryProductEntity, productBaseInfoEntity);
    }

    @Override
    public WarehouseListVO checkWarehouse(WarehouseCheckDTO warehouseCheckDTO) throws XbbException {
        WarehouseListVO warehouseListVO = new WarehouseListVO();
        warehouseListVO.setCanSelect(true);
        String corpid = warehouseCheckDTO.getCorpid();
        String dataId = warehouseCheckDTO.getDataId();
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        boolQueryBuilder.filter(termQuery(ParameterConstant.DEL,DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termQuery(InventoryEnum.getEsAttr4Keyword(InventoryEnum.WAREHOUSE_ID),dataId));
        boolQueryBuilder.filter(termQuery(InventoryEnum.getEsAttr4Keyword(InventoryEnum.INVENTORY_STATUS),InventoryNewStatusEnum.UNFINISHED.getCode()));
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, IndexTypeEnum.IDX_SAAS_INVENTORY.getType()));
        sourceBuilder.query(boolQueryBuilder);
        sourceBuilder.sort(new FieldSortBuilder("addTime").order(SortOrder.DESC));
        //分页
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 1, 1);
        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_INVENTORY.getIndex());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest,searchRequest, PaasFormDataEntityExt.class);
        if (esEntities.getTotalElements() > 0) {
            warehouseListVO.setCanSelect(false);
        }else{
            //需要再校验审批中数据
            List<PaasProcessDataEntity> inApprovalData = paasProcessDataModel.getInApprovalData(XbbRefTypeEnum.INVENTORY.getCode(), InventoryEnum.WAREHOUSE_ID.getAttr(), dataId, corpid);
            if (!inApprovalData.isEmpty()) {
                warehouseListVO.setCanSelect(false);
            }
        }
        return warehouseListVO;
    }

    @Override
    public void filterBatchStock(Map<Long, Map<String,JSONObject>>  productMap, List<Long> productIdList, String corpid) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("idIn", productIdList);
        List<ProductEntityExt> entitys = productModel.findEntitys(param);

        HashSet<Long> enableShelfProductIds = new HashSet<>();
        for (ProductEntityExt entity : entitys) {
            Integer enableBatchShelfLife = getIntegerOrDefaultFromFormData(entity.getData(), ProductEnum.ENABLE_BATCH_SHELF_LIFE.getAttr(), 0);
            if (Objects.equals(enableBatchShelfLife, 1)) {
                enableShelfProductIds.add(entity.getId());
            }
        }
        for (Long id : productIdList) {
            if (enableShelfProductIds.contains(id)) {
                Map<String, JSONObject> product = productMap.getOrDefault(id, new HashMap<>());
                for (String warehouseId : product.keySet()) {
                    JSONObject data = product.get(warehouseId);
                    data.put(SelectProductEnum.STOCK.getSaasAttr(), 0);
                }
            }
        }
    }

    @Override
    public void updateBatchLabelAttr(AddLabelDTO addLabelDTO, List<PaasFormDataEntityExt> addBatchList, Boolean addOrDelete) throws XbbException {
        InventoryUpdateBatchDTO inventoryUpdateBatchDTO = new InventoryUpdateBatchDTO();
        BeanUtil.copyProperties(addLabelDTO, inventoryUpdateBatchDTO);
        List<InventoryUpdateDTO> inventoryList = new ArrayList<>();
        addBatchList.forEach(item->{
            InventoryUpdateDTO updateDTO= new InventoryUpdateDTO();
            updateDTO.setData(item.getData());
            updateDTO.setId(item.getId());
            inventoryList.add(updateDTO);
        });
        inventoryUpdateBatchDTO.setInventoryList(inventoryList);
        updateBatch(inventoryUpdateBatchDTO);

    }

    @Override
    public void afterSaveForWorkflow(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        Long id = saasFormSaveDTO.getNewPaasFormDataEntity().getId();
        JSONObject newData = saasFormSaveDTO.getNewData();
        JSONArray productArray = newData.getJSONArray(InventoryEnum.PRODUCT.getAttr());
        Long warehouseId = FastJsonHelper.getLongOrDefaultFromFormData(newData, InventoryEnum.WAREHOUSE_ID.getAttr(), 0L);
        Long formId = saasFormSaveDTO.getNewPaasFormDataEntity().getFormId();
        // 更新盘点单关联产品
        saveProduct(saasFormSaveDTO.getCorpid(), id, warehouseId, productArray, formId,saasFormSaveDTO.getIsNew());
    }

    @Override
    public void afterSaveForUpdateWorkflow(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        Long id = saasFormSaveDTO.getNewPaasFormDataEntity().getId();
        JSONObject newData = saasFormSaveDTO.getNewData();
        JSONArray productArray = newData.getJSONArray(InventoryEnum.PRODUCT.getAttr());
        Long warehouseId = FastJsonHelper.getLongOrDefaultFromFormData(newData, InventoryEnum.WAREHOUSE_ID.getAttr(), 0L);
        Long formId = saasFormSaveDTO.getNewPaasFormDataEntity().getFormId();
        //已经出库或入库，不允许编辑
        boolean hasInOrOut = !Objects.equals(newData.getInteger(InventoryEnum.INSTOCK_ID.getAttr()),0) && !Objects.equals(newData.getInteger(InventoryEnum.OUTSTOCK_ID.getAttr()),0)
                && !Objects.isNull(newData.get(InventoryEnum.INSTOCK_ID.getAttr())) && !Objects.isNull(newData.get(InventoryEnum.OUTSTOCK_ID.getAttr()));
        Boolean productCanSee = saasFormSaveDTO.getSaasNeedRedundantAttrPoJo().getAttrCanSee(InventoryEnum.PRODUCT.getAttr());
        // 更新盘点单关联产品
        if (productCanSee && !hasInOrOut){
            saveProduct(saasFormSaveDTO.getCorpid(), id, warehouseId, productArray, formId,saasFormSaveDTO.getIsNew());
        }

    }


    @Override
    public void generateStockSheet(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        String corpid = saasFormSaveDTO.getCorpid();
        Long id = saasFormSaveDTO.getNewPaasFormDataEntity().getId();
        JSONObject newData = saasFormSaveDTO.getNewData();
        JSONArray productArray = newData.getJSONArray(InventoryEnum.PRODUCT.getAttr());
        Long warehouseId = FastJsonHelper.getLongOrDefaultFromFormData(newData, InventoryEnum.WAREHOUSE_ID.getAttr(), 0L);
        String inventoryType = FastJsonHelper.getStringOrDefaultFromFormData(newData, InventoryEnum.INVENTORY_TYPE.getAttr(), InventoryTypeEnum.STANDARD_INVENTORY.getCode());

        if (saasFormSaveDTO.getIsNew() && Objects.equals(inventoryType,InventoryTypeEnum.FAST_INVENTORY.getCode())) {
            // 本地盘点的关联产品取盘点仓库的产品陈本
            Map<Object,Double> costMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Object,Double> stockMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            productValidateHelp.getInventorySkuWarehouseOrBatchCost(productArray, warehouseId, saasFormSaveDTO.getCorpid(), costMap, stockMap);
            saasFormSaveDTO.setCostMap(costMap);

//            区分出入库
            JSONArray outstockProductArray = new JSONArray();
            JSONArray instockProductArray = new JSONArray();
            /**
             * 1. 当产品进行盘点单时，如果盘点产品数量大于库存数量，则会对盘点产品数量-库存数量的结果数量进行盘点入库；
             * 2. 当产品进行盘点单时，如果盘点产品数量小于库存数量，则会对库存数量盘点-产品数量的结果数量进行盘点出库；
             *
             */
            for (int i = 0; i < productArray.size(); i++) {
                JSONObject jsonObject = productArray.getJSONObject(i);
                Double num = jsonObject.getDouble(InventoryProductEnum.NUM.getAttr());
                Double stock = jsonObject.getDouble(InventoryProductEnum.STOCK.getAttr());
                jsonObject.put(OutstockProductEnum.WAREHOUSE.getAttr(),warehouseId);
                if (num - stock > 0){
                    jsonObject.put(OutstockProductEnum.NUM.getAttr(), Arith.sub(num, stock));
                    instockProductArray.add(jsonObject);
                }else if (num - stock < 0){
                    jsonObject.put(OutstockProductEnum.NUM.getAttr(), Arith.sub(stock, num));
                    outstockProductArray.add(jsonObject);
                }
            }
            newData.put(InventoryEnum.PRODUCT.getAttr(),outstockProductArray);
            SaasFormSaveDTO instockSaasFormSaveDTO = (SaasFormSaveDTO) CloneUtil.deepClone(saasFormSaveDTO);
            instockSaasFormSaveDTO.getNewData().put(InventoryEnum.PRODUCT.getAttr(),instockProductArray);
            boolean isCheck = concurrentLockAspect.checkStock(corpid);
            // 没开启负库存的才超发出库校验
            if (isCheck){
                // 盘点单出库超发控制
                if (CollectionUtils.isNotEmpty(outstockProductArray)){
                    concurrentLockAspect.checkInventory(outstockProductArray,warehouseId,corpid,true,XbbRefTypeEnum.INVENTORY.getCode());
                }
                // 盘点入库超发控制
                if (CollectionUtils.isNotEmpty(instockProductArray)){
                    concurrentLockAspect.checkInventory(instockProductArray,warehouseId,corpid,false,XbbRefTypeEnum.INVENTORY.getCode());
                }
            }

            //有跟新上有单据并发问题所以改成生成出入库单同步执行
            Runnable runnable = () -> {
                try {
                    if (CollectionUtils.isNotEmpty(outstockProductArray)) {
                        outstockService.generateOutStockSheet(saasFormSaveDTO);
                    }
                    if (CollectionUtils.isNotEmpty(instockProductArray)) {
                        instockService.generateInStockSheet(instockSaasFormSaveDTO);
                    }
                } catch (Exception e) {
                    if (isCheck){
                        // 没开启负库存的才回滚
                        concurrentLockAspect.InventorytockAndAssembleRollBack(instockProductArray, outstockProductArray);
                    }
                    LOG.error("InventoryServiceImpl.afterSave.generateOutStockSheet 执行出错：", e);
                }
            };
            threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);
        }
    }

    @Override
    public void batchEditAttr(InventoryEditAttrUpdateDTO inventoryEditAttrUpdateDTO) throws XbbException {
        try {
            List<InventoryUpdateDTO> inventoryList = new ArrayList<>();
            inventoryEditAttrUpdateDTO.getDataIdList().forEach((item) -> {
                InventoryUpdateDTO inventoryUpdateDTO = new InventoryUpdateDTO();
                inventoryUpdateDTO.setId(item);
                JSONObject data = ProSaveHelp.getBatchUpdateData(inventoryEditAttrUpdateDTO.getFieldEditedList());
                inventoryUpdateDTO.setData(data);
                inventoryList.add(inventoryUpdateDTO);
            });
            List<InventoryEntityExt> inventoryEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (!inventoryList.isEmpty()) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", inventoryEditAttrUpdateDTO.getCorpid());
                param.put("idIn", inventoryEditAttrUpdateDTO.getDataIdList());
                inventoryEntityList = inventoryModel.findEntitys(param);
                if (Objects.isNull(inventoryEntityList)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                }

                InventoryUpdateBatchDTO inventoryUpdateBatchDTO = new InventoryUpdateBatchDTO();
                BeanUtil.copyProperties(inventoryEditAttrUpdateDTO, inventoryUpdateBatchDTO);
                inventoryUpdateBatchDTO.setInventoryList(inventoryList);
                updateBatch(inventoryUpdateBatchDTO);
            }

            // 批量编辑日志
            List<String> updataItemList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<Long> dataIdList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (InventoryEntityExt item : inventoryEntityList) {
                dataIdList.add(item.getId());
                String serialNo = item.getSerialNo();
                updataItemList.add(serialNo);
            }
            String updataItem = StringUtils.join(updataItemList, "，");
            String userId = inventoryEditAttrUpdateDTO.getUserId();
            String corpid = inventoryEditAttrUpdateDTO.getCorpid();
            String loginUserName = inventoryEditAttrUpdateDTO.getLoginUserName();
            // 标签特殊处理
            Integer fieldType = inventoryEditAttrUpdateDTO.getFieldType();
            logHelp.analysisLabel(corpid, fieldType, inventoryEditAttrUpdateDTO.getIsFieldDependence(),inventoryEditAttrUpdateDTO.getLogFieldEditedList());

            String changedLogItemsStr = logHandleHelp.getChangedLogItemsStr(inventoryEditAttrUpdateDTO.getLogFieldEditedList());
            if (dataIdList.size() > 1) {
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_DATA_BATCH_ATTR), loginUserName, XbbRefTypeEnum.INVENTORY.getName(),
                        changedLogItemsStr, dataIdList.size());
                List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                InfoArrPojo infoArrPojo = new InfoArrPojo();
                infoArrPojo.setTitle(XbbRefTypeEnum.INVENTORY.getName());
                infoArrPojo.setContent(updataItem);
                infoArrPojoList.add(infoArrPojo);
                mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, loginUserName, OperateModuleTypeEnum.INVENTORY, OperateTypeEnum.EDIT,
                        "", "", memo, inventoryEditAttrUpdateDTO.getHttpHeader());
            } else if (Objects.equals(dataIdList.size(), 1)) {
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_DATA_ATTR), loginUserName, XbbRefTypeEnum.INVENTORY.getName(), updataItem,
                        changedLogItemsStr);
                mongoLogHelp.buildLog(corpid, userId, loginUserName, OperateModuleTypeEnum.INVENTORY, OperateTypeEnum.EDIT,
                        dataIdList.get(0).toString(), updataItem, memo, inventoryEditAttrUpdateDTO.getHttpHeader());
            }
        }catch (XbbException e) {
           throw e;
        } catch (Exception e) {
            LOG.error("inventoryService.batchEditAttr 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    @Override
    public void updateBatch(InventoryUpdateBatchDTO inventoryUpdateBatchDTO) throws XbbException {
        try {
            List<UpdateDataEntity> transferList = new ArrayList<>();
            String corpid = inventoryUpdateBatchDTO.getCorpid();
            inventoryUpdateBatchDTO.getInventoryList().forEach((item) -> {
                UpdateDataEntity updateDataEntity = ExplainUtil.getUpdateData(item.getId(), item.getData(), corpid);
                transferList.add(updateDataEntity);
            });
            if (!transferList.isEmpty()) {
                inventoryModel.updateBatch(transferList, corpid);
            }
        } catch (Exception e) {
            LOG.error("inventoryService.batchEditAttr 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    @Override
    public FormDataAddDTO formatExcelValue(ImportFormDataDTO importFormDataDTO, List<CellTitlePojo> titlePojoList, RowGroupPojo rowGroupPojo, List<FieldAttrEntityForImport> fieldAttrList) throws XbbException {
        FormDataAddDTO formDataAddDTO = new FormDataAddDTO();
        String corpid = importFormDataDTO.getCorpid();
        BeanUtil.copyProperties(importFormDataDTO, formDataAddDTO);
        // data 数据
        JSONObject dataJson = new JSONObject();

        List<List<CellValuePojo>> rowValueList = rowGroupPojo.getRowValueList();
        // 分组的第一条数据作为给实体对象赋值的数据
        List<CellValuePojo> cellValueList = rowValueList.get(0);

        // 遍历数据
        for (FieldAttrEntityForImport fieldAttrEntityForImport : fieldAttrList) {
            String attr = fieldAttrEntityForImport.getAttr();
            Integer fieldType = fieldAttrEntityForImport.getFieldType();
            String attrName = fieldAttrEntityForImport.getAttrName();
            Integer columnIndex = importHelper.getColumnIndexByTitle(titlePojoList, attrName, null);
            Object cellValue = importHelper.getValueByColumnIndex(cellValueList, columnIndex);

            if (Objects.equals(attr, InventoryEnum.PRODUCT.getAttr())) {
                importHelper.formatCommonProduct(titlePojoList, dataJson, rowValueList, fieldAttrEntityForImport, XbbRefTypeEnum.INVENTORY.getCode(), corpid);
            } else if (Objects.equals(fieldType, FieldTypeEnum.SUB_FORM.getType())) {
                importHelper.formatSubFormValue4Import(rowValueList, titlePojoList, importFormDataDTO, fieldAttrEntityForImport, dataJson);
            } else if (Objects.equals(attr, InventoryEnum.MANAGER_ID.getAttr())) {
                importHelper.formatOwnId4Import(formDataAddDTO, fieldAttrEntityForImport, cellValue);
            } else if (Objects.equals(attr, OutstockEnum.WAREHOUSE_ID.getAttr())) {
                importHelper.formatWareHouse4Import(dataJson, fieldAttrEntityForImport, attr, cellValue);
            } else if (Objects.equals(fieldType, FieldTypeEnum.SERIALNO.getType())) {
                if (Objects.isNull(cellValue) || StringUtil.isEmpty(cellValue.toString())) {
                    throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200022);
                }
                formDataAddDTO.setSerialNo(cellValue.toString());
            } else {
                if (Objects.isNull(cellValue) || StringUtil.isEmpty(cellValue.toString())) {
                    continue;
                }
                if (ImportHelper.commonHandleFieldType.contains(fieldAttrEntityForImport.getFieldType())) {
                    importHelper.formatCommonField(dataJson, fieldAttrEntityForImport, cellValue);
                } else if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA.getType())) {
                    importHelper.formatLinkData(cellValue, fieldAttrEntityForImport, dataJson);
                } else if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA_MULTI.getType())) {
                    importHelper.formatLinkDataMulti(cellValue, importFormDataDTO, fieldAttrEntityForImport, dataJson);
                } else {
                    dataJson.put(attr, cellValue);
                }
            }
        }
        // 加入当前库存数量，盘点单需要比对盘盈和盘亏
        JSONArray productJsonArray = dataJson.getJSONArray(InventoryEnum.PRODUCT.getAttr());
        JSONArray wareHouseArray = dataJson.getJSONArray(InventoryEnum.WAREHOUSE_ID.getAttr());
        if (wareHouseArray == null || wareHouseArray.isEmpty()) {
            throw new XbbException(WarehouseErrorCodeEnum.API_ERROR_244016.getCode(), WarehouseErrorCodeEnum.API_ERROR_244016.getMsg());
        }
        Long wareHouseId = wareHouseArray.getJSONObject(0).getLong(StringConstant.SAAS_LINK_BUSINESS_ID);
        Integer isCover = importFormDataDTO.getIsCover();
        if (!Objects.equals(1, isCover)) {
//            新建的时候
            WarehouseCheckDTO warehouseCheckDTO = new WarehouseCheckDTO();
            warehouseCheckDTO.setBusinessType(XbbRefTypeEnum.INVENTORY.getCode());
            warehouseCheckDTO.setDataId(wareHouseId.toString());
            warehouseCheckDTO.setCorpid(corpid);
            WarehouseListVO warehouseListVO = checkWarehouse(warehouseCheckDTO);
            if (!warehouseListVO.getCanSelect()) {
                throw new XbbException(ImportErrorCodeEnum.API_ERROR_235042.getCode(), ImportErrorCodeEnum.API_ERROR_235042.getMsg());
            }
        }
        List<Long> productIdList = new ArrayList<>();
        List<String> batchKeyList = new ArrayList<>();
        for (int i = 0; i < productJsonArray.size(); i++) {
            JSONObject productObj = productJsonArray.getJSONObject(i);
            Long productId = productObj.getJSONObject(SelectProductEnum.PRODUCT.getAttr()).getLong(StringConstant.DATA_ID);
            productIdList.add(productId);
            String batch = productObj.getString(SelectProductEnum.BATCH.getAttr());
            Long produceDate = productObj.getLong(SelectProductEnum.PRODUCE_DATE.getAttr()) == null ? 0L : productObj.getLong(SelectProductEnum.PRODUCE_DATE.getAttr());
            Long guaranteePeriod = productObj.getLong(SelectProductEnum.GUARANTEE_PERIOD.getAttr()) == null ? 0L : productObj.getLong(SelectProductEnum.GUARANTEE_PERIOD.getAttr());
            StringBuilder sb;
            if (StringUtil.isNotEmpty(batch)) {
                sb = new StringBuilder();
                sb.append(productId).append(StringConstant.CROSS).append(wareHouseId).append(StringConstant.CROSS).append(batch).append(StringConstant.CROSS).append(produceDate).append(StringConstant.CROSS).append(guaranteePeriod * TimeConstant.SECONDS_PER_DAY);
                batchKeyList.add(sb.toString());
            }
        }
        // 需要查询的字段
        List<String> fieldList = Arrays.asList(ProductWarehouseSubFormEnum.getAttrConnectDataByDbAttr("productId"), ProductWarehouseSubFormEnum.getAttrConnectDataByDbAttr("num"));
        Map<Long, ProductWarehouseEntity> productWarehouseMap = productWarehouseModel.getWarehouseProductList(importFormDataDTO.getCorpid(), wareHouseId, productIdList, fieldList);

        Map<String, ProductStockEntity> productBatchWarehouseMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (!batchKeyList.isEmpty()) {
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("del", DelEnum.NORMAL.getDel());
            params.put(ParameterConstant.CORPID, corpid);
            params.put("batchKeyIn", batchKeyList);
            params.put("warehouseChecked", 1);
            List<ProductStockEntity> productStockEntities = productStockModel.findEntitys(params);
            productStockEntities.forEach(item -> {
                productBatchWarehouseMap.put(item.getBatchKey(), item);
            });
        }
        JSONArray tempJsonArray = new JSONArray();
        StringBuilder sb;
        for (int i = 0; i < productJsonArray.size(); i++) {
            JSONObject productObj = productJsonArray.getJSONObject(i);
            Long productId = productObj.getJSONObject(SelectProductEnum.PRODUCT.getAttr()).getLong(StringConstant.DATA_ID);
            String batch = productObj.getString(SelectProductEnum.BATCH.getAttr());
            Long produceDate = productObj.getLong(SelectProductEnum.PRODUCE_DATE.getAttr()) == null ? 0L : productObj.getLong(SelectProductEnum.PRODUCE_DATE.getAttr());
            Long guaranteePeriod = productObj.getLong(SelectProductEnum.GUARANTEE_PERIOD.getAttr()) == null ? 0L : productObj.getLong(SelectProductEnum.GUARANTEE_PERIOD.getAttr());
            if (StringUtil.isNotEmpty(batch)) {
                sb = new StringBuilder();
                sb.append(productId).append(StringConstant.CROSS).append(wareHouseId).append(StringConstant.CROSS).append(batch).append(StringConstant.CROSS).append(produceDate).append(StringConstant.CROSS).append(guaranteePeriod * TimeConstant.SECONDS_PER_DAY);
                ProductStockEntity productStockEntity = productBatchWarehouseMap.get(sb.toString());
                if (productStockEntity != null) {
                    productObj.put(SelectProductEnum.STOCK.getAttr(), productStockEntity.getNum());
                    if (Objects.nonNull(productStockEntity.getGuaranteePeriod())) {
                        productObj.put(SelectProductEnum.GUARANTEE_PERIOD.getAttr(), Arith.div(productStockEntity.getGuaranteePeriod(), 86400));
                    }
                    productObj.put(SelectProductEnum.PRODUCE_DATE.getAttr(), productStockEntity.getProduceDate());
                } else {
                    throw new XbbException(ImportErrorCodeEnum.API_ERROR_235032.getCode(), ImportErrorCodeEnum.API_ERROR_235032.getMsg());
                }
            } else {
                ProductWarehouseEntity productWarehouse = productWarehouseMap.get(productId);
                if (productWarehouse != null) {
                    productObj.put(SelectProductEnum.STOCK.getAttr(), productWarehouse.getNum());
                } else {
                    //以前盘点单 产品与仓库未关联时不允许盘 现在允许盘了
                    productObj.put(SelectProductEnum.STOCK.getAttr(), 0d);
                }
            }
            tempJsonArray.add(productObj);
        }
        dataJson.put(InventoryEnum.PRODUCT.getAttr(), tempJsonArray);
        formDataAddDTO.setDataList(dataJson);
        //21563 【盘点单】导入不存在的产品批次号也可以正确导入
        checkBatchIsRight(true, productJsonArray, importFormDataDTO.getCorpid(),wareHouseId);
        return formDataAddDTO;
    }

    @Override
    public void formatExportValue(List<PaasFormDataEntityExt> paasFormDataESList, FormDataListDTO formDataListDTO, List<FieldAttrEntityForImport> fieldAttrList) throws XbbException {
        // 所有产品map
        List<Long> idList = new ArrayList<>();
        paasFormDataESList.forEach(item -> idList.add(item.getDataId()));
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put(ParameterConstant.CORPID, formDataListDTO.getCorpid());
        params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        List<ProductEntityExt> productList = productModel.findEntitys(params);
        Map<Long, ProductEntityExt> productMap = new HashMap<>();
        productList.forEach(item -> productMap.put(item.getId(), item));
        // 盘点关联产品map
        params.put("inventoryIdIn", idList);
        params.put("orderByStr","sort");
        List<InventoryProductEntity> inventoryProductList = inventoryProductModel.findEntitys(params);
        Map<Long, List<InventoryProductEntity>> inventoryProductMap = new HashMap<>();
        inventoryProductList.forEach(item -> {
            Long refId = item.getInventoryId();
            if (inventoryProductMap.containsKey(refId)) {
                inventoryProductMap.get(refId).add(item);
            } else {
                List<InventoryProductEntity> productEntityList = new ArrayList<>();
                productEntityList.add(item);
                inventoryProductMap.put(refId, productEntityList);
            }
        });

        // 库存信息map
        params.remove("inventoryIdIn");
        params.remove("orderByStr");
        params.put("refType", XbbRefTypeEnum.INVENTORY_PRODUCT.getCode());
        List<ProductBaseInfoEntity> stockInfoList = productBaseInfoModel.findEntitys(params);
        Map<Long, ProductBaseInfoEntity> stockInfoMap = new HashMap<>();
        stockInfoList.forEach(item -> stockInfoMap.put(item.getRefId(), item));

        // 分仓库存信息
        Set<Long> warehouseIdList = new HashSet<>();
        Set<Long> productIdList = new HashSet<>();
        for (InventoryProductEntity inventoryProductEntity : inventoryProductList) {
            Long productId = inventoryProductEntity.getProductId();
            Long warehouseId = inventoryProductEntity.getWarehouseId();
            warehouseIdList.add(warehouseId);
            productIdList.add(productId);
        }


        // 产品，库存产品
        FieldAttrEntityForImport productFieldAttr = new FieldAttrEntityForImport();
        for (FieldAttrEntityForImport item : fieldAttrList) {
            if (Objects.equals(item.getAttr(), InventoryEnum.PRODUCT.getAttr())) {
                productFieldAttr = item;
            }
        }
        Map<String, MultiUnitItemPoJo> groupBaseUnitStringMap = relativeProductHelp.getGroupBaseUnitStringMap(formDataListDTO.getCorpid());

        // 暂时只处理产品
        for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataESList) {
            JSONObject formDataObj = paasFormDataEntityExt.getData();
            String productAttr = productFieldAttr.getAttr();
            Long dataId = paasFormDataEntityExt.getDataId();
            List<InventoryProductEntity> inventoryProductEntityList = inventoryProductMap.get(dataId);
            if (inventoryProductEntityList == null || inventoryProductEntityList.size() == 0) {
                formDataObj.put(productAttr, new JSONArray());
                continue;
            }
            JSONArray productArray = new JSONArray();
            for (InventoryProductEntity inventoryProductEntity : inventoryProductEntityList) {
                Long productId = inventoryProductEntity.getProductId();
                Long warehouseId = inventoryProductEntity.getWarehouseId();
                Double num = inventoryProductEntity.getProductNum();
                ProductEntityExt productEntityExt = productMap.get(inventoryProductEntity.getProductId());
                if (Objects.isNull(productEntityExt)) {
                    continue;
                }
                JSONObject productData =  productEntityExt.getData();
                // 产品信息转换
                JSONObject productObj = inventoryProductEntity.getData() == null ? new JSONObject() : inventoryProductEntity.getData();
                importHelper.formatProduct4Export(productMap, null, productId, num, null, productObj);
                importHelper.formatBatch4Export(productObj);
                productObj.put(SelectProductEnum.UNIT.getAttr(), productData.get(ProductEnum.UNIT.getAttr()));
                productObj.put(ProductEnum.ENABLE_MULTI_UNIT.getAttr(), productData.getIntValue(ProductEnum.ENABLE_MULTI_UNIT.getAttr()));
                if (Objects.equals(productObj.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getAttr()), BasicConstant.ONE)){
                    productObj.put(ProductEnum.UNIT.getAttr(), groupBaseUnitStringMap.getOrDefault(productObj.getString(ProductEnum.UNIT.getAttr()), new MultiUnitItemPoJo()).getBaseValue());
                }
                productArray.add(productObj);
                // 库存产品信息转换
               /* ProductBaseInfoEntity baseInfoEntity = stockInfoMap.get(inventoryProductEntity.getId());
                importHelper.formatBaseInfo4Export(productObj, baseInfoEntity);*/
            }
            formDataObj.put(productAttr, productArray);
        }
    }





    @Override
    public void dataConsistencyUpdateWarehouse(String corpid, Long dataId, String name) throws XbbException {
        try {
            BoolQueryBuilder filter = boolQuery()
                    .filter(termQuery("corpid.keyword", corpid))
                    .filter(termQuery("del", 0))
                    .filter(termQuery("data." + InventoryEnum.WAREHOUSE_ID.getAttr() + ".keyword", dataId));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(FieldTypeEnum.DATAID.getAlias());
            List<PaasFormDataEntityExt> esEntities = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_INVENTORY, filter, PaasFormDataEntityExt.class, fieldList);
            Set<Long> ids = new HashSet<>();
            for (PaasFormDataEntityExt esEntity : esEntities) {
                ids.add(esEntity.getDataId());
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("idIn", ids);
            param.put("del", 0);
            List<InventoryEntityExt> inventoryEntitys = inventoryModel.findEntitys(param);
            if (Objects.nonNull(inventoryEntitys) && !inventoryEntitys.isEmpty()) {
                List<InventoryUpdateDTO> updateDTOList = new ArrayList<>();
                for (InventoryEntityExt entityExt : inventoryEntitys) {
                    InventoryUpdateDTO inventoryUpdateDTO = new InventoryUpdateDTO();
                    inventoryUpdateDTO.setId(entityExt.getId());
                    JSONObject data = new JSONObject();
                    data.put(InventoryEnum.WAREHOUSE_ID_LINKED_TEXT.getAttr(), name);
                    inventoryUpdateDTO.setData(data);
                    updateDTOList.add(inventoryUpdateDTO);
                }
                InventoryUpdateBatchDTO inventoryUpdateBatchDTO = new InventoryUpdateBatchDTO();
                inventoryUpdateBatchDTO.setCorpid(corpid);
                inventoryUpdateBatchDTO.setInventoryList(updateDTOList);
                updateBatch(inventoryUpdateBatchDTO);
            }
        } catch (Exception e) {
            LOG.error("InventoryServiceImpl.dataConsistencyUpdateWarehouse 出错， corpid=" + corpid + "  warehouseId=" + dataId + "  warehouseName=" + name, e);
        }
    }

    /**
     * 获取采购合同产品
     *
     * @param businessProductListDTO 入参
     * @author long.rao
     * @date 2019-08-28 10:24
     **/
    @Override
    public ProductSummaryVO summaryProductList(BusinessProductListDTO businessProductListDTO) throws XbbException {
        // 获取参数
        String corpid = businessProductListDTO.getCorpid();
        Long dataId = businessProductListDTO.getDataId();

        Map<String, Object> modelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        modelMap.put(ParameterConstant.CORPID, corpid);
        modelMap.put("inventoryId", dataId);
        modelMap.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        modelMap.put("columns", "product_num");
        List<InventoryProductEntity> inventoryProductEntities = inventoryProductModel.findEntitys(modelMap);

        ProductSummaryVO businessProductListVO = new ProductSummaryVO();

        Double num = 0D;
        for (InventoryProductEntity inventoryProductEntity : inventoryProductEntities) {
            Double productNum = inventoryProductEntity.getProductNum() != null ? inventoryProductEntity.getProductNum(): 0D;
            num = Arith.add(num, productNum);
        }
        Integer productSize = inventoryProductEntities.size();
        String summaryInfo = String.format(I18nMessageUtil.getMessage(StringConstant.PRODUCTS_TYPE_NUM), productSize, Arith.doubleToBigDecimal(num));
        businessProductListVO.setSummaryInfo(summaryInfo);
        return businessProductListVO;
    }

    @Override
    public void updateBatchByBusinessRule(InventoryUpdateByBusinessRuleDTO inventoryUpdateByBusinessRuleDTO) throws XbbException {
        try {
            String corpid = inventoryUpdateByBusinessRuleDTO.getCorpid();
            List<PaasFormDataEntityExt> formDataList = inventoryUpdateByBusinessRuleDTO.getFormDataList();
            List<UpdateDataEntity> updateList = ExplainUtil.getUpdateValueByBusinessRule(formDataList, corpid, inventoryUpdateByBusinessRuleDTO.getOperations());

            if (!updateList.isEmpty()) {
                inventoryModel.updateBatch(updateList, corpid);
                RuleBusinessLogDTO businessLogDTO = new RuleBusinessLogDTO();
                BeanUtil.copyProperties(inventoryUpdateByBusinessRuleDTO, businessLogDTO);
                businessLogDTO.setFormDataList(formDataList);
                ruleBusinessLogger.writeLog(businessLogDTO, updateList);
            }
        } catch (Exception e) {
            LOG.error("inventoryService.updateFormDataByBusinessRule根据业务规则更新数据出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    @Override
    public void formatBatchExplain(List<FieldAttrEntity> fieldAttrEntityList, String enable) {
        String attr = InventoryEnum.PRODUCT.getAttr();
        BatchSeqExplainHelp.getInstance().formatExplain4BatchAffectProductAttr(fieldAttrEntityList, enable, attr);
    }

    @Override
    public void formatBatchOrSeqExplain(List<FieldAttrEntity> fieldAttrEntityList, String enable, String alias) {
        if (CompanyConfigEnum.ENABLE_BATCH_SHELF_MANAGEMENT.getAlias().equals(alias)) {
            formatBatchExplain(fieldAttrEntityList, enable);
        }
    }
}

